Windows Cmd: cannot get the input character properly - c

I cannot get my input character value properly. Here is my code:
#include <stdlib.h>
void main()
{
char buf_in[32] = { 0 };
printf("input: ");
gets_s(buf_in, 32);
for (int i = 0; i < 32; i++)
printf("%02x ", buf_in[i]);
getchar();
}
I input the character by <alt-254>, but the result is 74 00 00 ..., not fe 00 00 ....
Here is my local environment: chcp 936.
And I test in some different local environments (ANSI code page 936):
1. OEM code page 936 result : 74 00 00 ...
2. OEM code page 65001 result : 00 00 00 ... (weird)
3. OEM code page 1250 result : 3f 00 00 ...
4. OEM code page 437 result : 5f 00 00 ...

I think ALT-codes are not supported by windows console. Please look here:
Alt Codes in Batch
You can try to put ALT-code (or any other data...) in file and then redirect input to Your program:
./prog.exe < input.txt
To be sure that you put proper value in file i suggest to use hex editor (like XVI32)
Does it work for other characters?

Related

Reading data pointed to by an address

working on my reversing skillset here and I came upon something I thought i understood but I managed to confuse myself.
Working in C mainly
My function returns me an address for the information I want to access.
LRESULT ret = SendMessage(hComboBox, CB_GETITEMDATA, (WPARAM)0 , (LPARAM) 0);
// the exact function doesn't really matter here.
printf("Address: %p\n", ret); // Output is 09437DF8
A dump of this address results in
09437DF8 A0 55 E8 12
This is the address (note endianness) of the data I really want to read.
12e855A0
12 E8 55 A0 - 30 00 3A 00 30 00 33 00 3A 00 32 00 32 00 00 00 - UNICODE "0:03:22"
Now I'm fairly certain this is just basic pointers/referencing/de-referencing but i cant wrap my head what I have to do to read this value pragmatically.
wprintf(L"%s\n", <value at address pointed to by ret>);
// Yes its a null terminated string
// Im working via injected dll, so no access violations
// string is unicode
Perhaps something like this?
#include <stdio.h>
#include <wchar.h>
int main()
{
wchar_t *name = L"UNICODE String";
void **ret = (void **)&name;
wprintf(L"%ls \n", *(wchar_t **)ret);
return 0;
}

Getting MAC address in c and writing it to a txt file

Following is my code. In this program I use system function and passe a command line argument to get the mac address of the pc and then write it into the txt file. txt file is creating successfully. But When I try to open the txt file which was created it wont show anything. It show letter M and some blank spaces. Any idea why is this happening ? Thank you.
#include<stdio.h>
int main()
{
system("wmic nic where (AdapterTypeId=0 AND netConnectionStatus=2) get MACAddress >macaddress.txt");
FILE * fpointer=fopen("macaddress.txt","r");
char buffer[500];
while(!feof(fpointer)){
fgets(buffer,500,fpointer);
puts(buffer);
}
fclose(fpointer);
}
This will do what you want, but if instead of just printing the contents of the file you actually want to do something with it and you need the text as ASCII you'll need to perform that conversion yourself from wide characters.
Since this particular file is just normal letters and numbers text you can convert the wide string to narrow with sprintf.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
system("wmic nic where (AdapterTypeId=0 AND netConnectionStatus=2) get MACAddress > macaddress.txt");
//Binary mode tells fgetws to read wide characters instead of multi-byte.
FILE * fp = fopen("macaddress.txt", "rb");
if (fp)
{
wchar_t buffer[500] = { 0 };
fread(buffer, 1, 2, fp); //read and discard BOM
while (fgetws(buffer, 500, fp))
{
// %ls means the parameter is a wide string.
// %S also works in Visual Studio
printf("%ls", buffer);
//Convert wide characters to ASCII
//This assumes the wide characters are all in the ASCII range
char ascii[500] = { 0 };
sprintf(ascii, "%ls", buffer);
printf("%s", ascii);
}
fclose(fp);
}
return 0;
}
It is not an ASCII encoded file. Here is a dump
0 1 2 3 4 5 6 7 8 9 A B C D E F
0000:0000 FF FE 4D 00 41 00 43 00 41 00 64 00 64 00 72 00  ■M.A.C.A.d.d.r.
0000:0010 65 00 73 00 73 00 20 00 20 00 20 00 20 00 20 00 e.s.s. . . . . .
0000:0020 20 00 20 00 20 00 20 00 0D 00 0A 00
etc so as not to reveal my MAC address.
Note too it contains zeros which will terminate any string output after reading with fgets.
My text editor (Notepad++) shows the correct content because it sets the right text format automatically.

fread only reading in from the first time I ran the program

When I first run I would add 3 records, which gives me a count of 3. Then I fwrite the count into a bin file, and the records into a bin file, then I close the program.
When I reopen it and then I fread in and it will give me my 3 records and a count of 3. But from there on, no matter if I back up or when I read in, it will give me the same count 3 and 3 records, though since the count isn't being updated either this may be why fread is only reading in the first time records.
I am not sure why the counter isn't updating. Both fread and fwrite are returning = success so I am not sure what`s up.
void backUp(PAYROLL employee[], long int *pCounter)
{
FILE *counter;
errno_t result1 = fopen_s(&counter, "c:\\myFiles\\counter.bin", "a+b");
if (result1 == 0){
fwrite(pCounter, sizeof(long int), 1, counter);
fclose(counter);
}
else
printf("Back up of counter failed! error:%d",result1);
FILE *record;
errno_t result2 = fopen_s(&record, "c:\\myFiles\\record.bin", "a+b");
if (result2 == 0){
fwrite(employee, *pCounter *sizeof(PAYROLL), 1, record);
fclose(record);
}
else
printf("Back up of record failed! error:%d", result2);
}
void upload(PAYROLL employee[], long int *pCounter)
{
FILE *counter;
errno_t result1 = fopen_s(&counter, "c:\\myFiles\\counter.bin", "a+b");
if (result1 == 0){
result = fread(pCounter, sizeof(long int), 1, counter);
fclose(counter);
printf("Counter:%d", *pCounter);
}
else
printf("Upload up of counter failed!");
FILE *record;
errno_t result2 = fopen_s(&record, "c:\\myFiles\\record.bin", "r+b");
if (result2 == 0)
{
result2 = fread(employee, *pCounter *sizeof(PAYROLL), 1, record);
printf("Upload successful!\n");
fclose(record);
}
else
printf("Error opening file!");
}
Transferring the most salient comments into an answer.
Weathervane commented:
How do you know that fread and fwrite are returning "success" when you have not checked their return value?
Jude commented:
I look through the debugger and step in to the function, result is giving me their success return values (if that's how it works).
Weathervane commented:
You still need that in the program. Without that sort of checking, your code will be blown over by a puff of wind.
Dmitri correctly observed:
Looks like everywhere you open in append mode "a+b" you should probably be using something else ("rb" in upload() and "wb" in backUp() possibly?)
Jude commented:
I don't understand, is there a specific function for error checking? As I had always thought that error checking was just looking at what goes in the value of result and then I can go check what the value means?
Look at the specification of fread() and
fwrite(). They return the number of records written or read, which may be less than the number requested. If you get a short write, then you have a problem — maybe out of disk space. If you get a short read, it may be that you requested 100 records but there were only 1 or 10 or 99 available to read (or there was an error). If you don't capture and check the return value, you've no idea what happened.
Jude commented:
I see they read and write 1, but it still stores the first 3 elements of my struct array. I assume it's one because it's only writing my array?
fread() (and fwrite() too) give you considerable flexibility because you can supply the size of an item and the number of items separately. You use:
result2 = fread(employee, *pCounter *sizeof(PAYROLL), 1, record);
This tells fread() to read 1 item of size *pCounter * sizeof(PAYROLL). You will get a result of 1 (success) or 0 (failure). You could have specified:
result2 = fread(employee, sizeof(PAYROLL), *pCounter, record);
which would tell you how many records of size sizeof(PAYROLL) were read, up to a maximum of the value in *pCounter. You might get 0 or 1 or …
Here is some workable code that does more or less what's required. The main() program demonstrates working with 1, 2 and 3 records (and the names are a few kings and queens of England, along with the year of their ascension to the throne as their employee ID number). I had to create a minimal payroll structure since the question didn't provide one.
#include <stdio.h>
#include <string.h>
#include <errno.h>
typedef struct PAYROLL
{
long emp_id;
char emp_name[32];
} PAYROLL;
static const char counter_bin[] = "counter.bin";
static const char records_bin[] = "records.bin";
static
void backUp(PAYROLL employee[], long int *pCounter)
{
FILE *counter = fopen(counter_bin, "wb");
if (counter != 0){
fwrite(pCounter, sizeof(long int), 1, counter);
fclose(counter);
}
else
fprintf(stderr, "Back up of counter failed! error: %d %s\n", errno, strerror(errno));
FILE *record = fopen(records_bin, "wb");
if (record != 0){
fwrite(employee, *pCounter *sizeof(PAYROLL), 1, record);
fclose(record);
}
else
fprintf(stderr, "Back up of records failed! error: %d %s\n", errno, strerror(errno));
}
static
void upload(PAYROLL employee[], long int *pCounter)
{
FILE *counter = fopen(counter_bin, "rb");
if (counter != 0){
size_t result = fread(pCounter, sizeof(long int), 1, counter);
fclose(counter);
if (result != 0)
printf("Counter: %ld\n", *pCounter);
else
fprintf(stderr, "Failed to read counter\n");
}
else
fprintf(stderr, "Upload up of counter failed!\n");
FILE *record = fopen(records_bin, "r+b");
if (record != 0)
{
size_t result2 = fread(employee, *pCounter * sizeof(PAYROLL), 1, record);
if (result2 == 1)
printf("Upload successful!\n");
else
fprintf(stderr, "Failed to read records!\n");
fclose(record);
}
else
fprintf(stderr, "Error opening file!");
}
int main(void)
{
PAYROLL emps[] =
{
{ 1066, "William the Conqueror" },
{ 1819, "Victoria" },
{ 1689, "William and Mary" },
};
for (int i = 1; i <= 3; i++)
{
long emp_count = i;
printf("Employee count = %ld\n", emp_count);
backUp(emps, &emp_count);
upload(emps, &emp_count);
for (int j = 0; j < emp_count; j++)
printf("%4ld: %s\n", emps[j].emp_id, emps[j].emp_name);
}
return 0;
}
Note that I've factored out the file names so that you only have to change a single line to change the files used. Sample output:
$ Employee count = 1
Counter: 1
Upload successful!
1066: William the Conqueror
Employee count = 2
Counter: 2
Upload successful!
1066: William the Conqueror
1819: Victoria
Employee count = 3
Counter: 3
Upload successful!
1066: William the Conqueror
1819: Victoria
1689: William and Mary
$ odx counter.bin
0x0000: 03 00 00 00 00 00 00 00 ........
0x0008:
$ odx records.bin
0x0000: 2A 04 00 00 00 00 00 00 57 69 6C 6C 69 61 6D 20 *.......William
0x0010: 74 68 65 20 43 6F 6E 71 75 65 72 6F 72 00 00 00 the Conqueror...
0x0020: 00 00 00 00 00 00 00 00 1B 07 00 00 00 00 00 00 ................
0x0030: 56 69 63 74 6F 72 69 61 00 00 00 00 00 00 00 00 Victoria........
0x0040: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0x0050: 99 06 00 00 00 00 00 00 57 69 6C 6C 69 61 6D 20 ........William
0x0060: 61 6E 64 20 4D 61 72 79 00 00 00 00 00 00 00 00 and Mary........
0x0070: 00 00 00 00 00 00 00 00 ........
0x0078:
$
(odx is just a hex dump program. Pick your own program that does an equivalent job — od -c is a fallback, though I don't particularly like its formatting.)
I see many faults in your program.
Firstly, you are writing long ints and PAYROLL structures directly to a file. You should never do that, as structures and integers have a machine-dependent representation and if you write the files on one machine (let's say 32-bit machine) and read them on another machine (let's say 64-bit machine) then you might run into problems.
Secondly, you're not checking the return value of fread(). It should be always checked.
Thirdly, you're assigning the return value of fread() to an errno_t. Are you sure you really want to do that?
If you want to have the answer to the actual problem, consider updating the source code to fix the mistakes I pointed out and consider improving the English language in your question. Furthermore, you should provide a complete example, i.e. one that contains the definition of PAYROLL. When you know the actual return value of fread(), perhaps the problem will be easier to track down then.

how to remove space between characters of a string using wide char to multibytes?

I have a file open in winhex look like follow.
1F 00 48 3A 18 00 00 00 53 00 70 00 6F 00 75 00
73 00 65 00 5F 00 61 00 7A 00 61 00 6D 00 00 00
I am reading the above hex data from file and write it to a text file . My code is as follow.
#include<stdlib.h>
#include<stdio.h>
#include<iostream.h>
int main()
{
FILE *pFile, *tempFile;
char *Main_buffer;
int nOfRecord, TotalSize, data=0;
pFile = fopen("C:\\wab files\\Main.wab", "rb");
if(pFile == NULL)
{
fputs("file error", stderr);
exit(1);
}
tempFile = fopen("C:\\myfile.text","wb");
if(tempFile == NULL)
{
fputs("file not open", stderr);
exit(2);
}
fread(&nOfRecord, 1, 4, pFile);
fread(&TotalSize, 1, 4, pFile);
data = TotalSize;
char* Main_buffer = (char*)malloc(data*sizeof(data));
fread(Main_buffer, 1, TotalSize, pFile);
fwrite(Main_buffer, 1, TotalSize, tempFile);
free(Main_buffer);
return 0;
}
This code gives a text file in which data is written as follow.
p a l # g m a i l . c o
In above data there is a space between each character . How to remove space from the data, and write in a text file . Please explain by writing some code as an example for wide char to multi bytes . Thanks you in advance .
There are basically 2 ways of doing it:
Manually removing spaces from the generated ASCII thing.
Use a library to do the work for you (of course if you are allowed to). My preference goes toward
http://en.wikipedia.org/wiki/Iconv
which (as said on the Wikipedia page) has a free implementation in GCC so you can try to play with it.
And here the link to the Linux lib:
http://www.gnu.org/software/libiconv/#TOCintroduction
UPDATE
Here is an example in C of how to use libiconv:
http://www.gnu.org/software/libc/manual/html_node/iconv-Examples.html
Try using strtok() from < string.h > .

Why can fread() not work (skipping bytes) under Msys/MinGw?

Trying to build Xuggler under Windows. Xuggler is core native code functions wrapped into Java for sound processing purposes (including ffmpeg).
My Windows is x64 Win 7 prof, but all used libraries are 32bit. I am running build procedure under MinGW/MSys, from under Msys shell with the followinf script:
#!/bin/sh
export JAVA_HOME=/C/Program\ Files\ \(x86\)/Java/jdk1.6.0_25
export XUGGLE_HOME=/C/Xuggler
PATH=$XUGGLE_HOME/bin:/C/Program\ Files\ \(x86\)/Java/jdk1.6.0_25/bin:/d/APPS/msysgit/msysgit/bin/git:/D/APPS/MinGW/bin:/bin:/D/APPS/apa che-ant-1.8.2/bin:/D/Users/Dims/Design/MinGW/Util:$PATH
ant -Dbuild.m64=no run-tests
Ant target contains some tests at the end, which give an error. The error follows
[exec] Running 6 tests..
[exec] In StdioURLProtocolHandlerTest::testRead:
[exec] ../../../../../../../../../test/csrc/com/xuggle/xuggler/io/StdioURLProtocolHandlerTest.cpp:108: Error: Expected (4546420 == totalBytes), found (4546420 != 1042)
[exec] In StdioURLProtocolHandlerTest::testReadWrite:
[exec] ../../../../../../../../../test/csrc/com/xuggle/xuggler/io/StdioURLProtocolHandlerTest.cpp:185: Error: Expected (4546420 == totalBytes), found (4546420 != 1042)
[exec] In StdioURLProtocolHandlerTest::testSeek:
[exec] ../../../../../../../../../test/csrc/com/xuggle/xuggler/io/StdioURLProtocolHandlerTest.cpp:139: Error: Expected (4546420 == totalBytes), found (4546420 != 1042)
[exec] .
[exec] Failed 3 of 6 tests
[exec] Success rate: 50%
[exec] FAIL: xugglerioTestStdioURLProtocolHandler.exe
UPDATE 1
The test code is follows:
int32_t totalBytes = 0;
do {
unsigned char buf[2048];
retval = handler->url_read(buf, (int)sizeof(buf));
if (retval > 0)
totalBytes+= retval;
} while (retval > 0);
VS_TUT_ENSURE_EQUALS("", 4546420, totalBytes);
While the url_read code is follows:
int
StdioURLProtocolHandler :: url_read(unsigned char* buf, int size)
{
if (!mFile)
return -1;
return (int) fread(buf, 1, size, mFile);
}
I don't understand, under what circumstances it can return 1042??? May be 64 bits play here somehow?
UPDATE 2
I printed out filename used and it was
d:/......./../../../test/fixtures/testfile.flv
the path is correct, but started with d:/ not with /d/
Can this play a role under Msys?
UPDATE 3
I have compared the readen bytes with real content of the test file and found, that fread() skips some bytes for some reason. Don't know which bytes yet, probably these are CR/LF
UPDATE 4
Not related with CR/LF I guess.
Original bytes are
46 4C 56 01 05 00 00 00 09 00 00 00 00 12 00 00 F4 00 00 00 00 00 00 00 02 00 0A 6F 6E 4D 65 74 61 44 61 74 61 08 00 00 ...
readen bytes are
46 4C 56 15 00 09 00 00 12 00 F4 00 00 00 02 0A 6F 6E 4D 65 74 61 44 61 74 61 80 00 B0 86 47 57 26 17 46 96 F6 E0 40 62 ...
This is FLV file begin. I don't understand the ptinciple of corruption.
How can 01 05 00 00 transform to just 15???
UPDATE 5
File opening done like following
void
StdioURLProtocolHandlerTest :: testRead()
{
StdioURLProtocolManager::registerProtocol("test");
URLProtocolHandler* handler = StdioURLProtocolManager::findHandler("test:foo", 0,0);
VS_TUT_ENSURE("", handler);
int retval = 0;
retval = handler->url_open(mSampleFile, URLProtocolHandler::URL_RDONLY_MODE);
VS_TUT_ENSURE("", retval >= 0);
int32_t totalBytes = 0;
printf("Bytes:\n");
do {
//...
url_open() function follows:
int StdioURLProtocolHandler :: url_open(const char *url, int flags)
{
if (!url || !*url)
return -1;
reset();
const char * mode;
switch(flags) {
case URLProtocolHandler::URL_RDONLY_MODE:
mode="r";
break;
case URLProtocolHandler::URL_WRONLY_MODE:
mode="w";
break;
case URLProtocolHandler::URL_RDWR_MODE:
mode="r+";
break;
default:
return -1;
}
// The URL MAY contain a protocol string. Find it now.
char proto[256];
const char* protocol = URLProtocolManager::parseProtocol(proto, sizeof(proto), url);
if (protocol)
{
size_t protoLen = strlen(protocol);
// skip past it
url = url + protoLen;
if (*url == ':' || *url == ',')
++url;
}
// fprintf(stderr, "protocol: %s; url: %s; mode: %s\n", protocol, url, mode);
mFile = fopen(url, mode);
if (!mFile)
return -1;
return 0;
}
Should be fixed in the GIT repository on the cross_compile branch as of today. I will roll this into tip of tree later this week / early next week.
Now the stdio handler opens all files as binary.

Resources