Reputation:
I have an executable file called re.exe, I want to read its content in the binary form and then show that content in the console. I write the following code but it doesn't show the content of the binary file in the console. What's the problem?
#include <stdio.h>
#include <ctype.h>
void readFile(const char *fileName) {
FILE *file;
file = fopen(fileName, "rb");
if (file != NULL) {
char ch;
while ((ch = fgetc(file)) != EOF) {
if (isprint(ch)) {
printf("%x", ch);
}
else {
printf("%02x", ch);
if (ch == '\n') {
fputs("\n", stdout);
}
}
}
fclose(file);
}
}
int main() {
readFile("re.exe");
return 0x0;
}
Upvotes: 2
Views: 997
Reputation: 857
The problem is the implicit casting of the return value of fgetc
from int
to char
.
Since EOF
is defined as (-1)
(at least in glibc), the returned char
(which is by default signed in GCC) is converted to an int
(with sign extension) as specified in section 6.3.1.8 of the C99 standard:
If both operands have the same type, then no further conversion is needed.
Otherwise, if both operands have signed integer types or both have unsigned integer types, the operand with the type of lesser integer conversion rank is converted to the type of the operand with greater rank.
As a result, the character 0xff
is converted to 0xffffffff
and is actually equal to the value of EOF
which causes the loop to end prematurely before reading all the file.
In addition, when printing the character with printf("%x", ch)
or printf("%02x", ch)
, the character is again converted to an int
(see here) and thus you can see for example the output 0xffffff90
for the character 0x90
.
In summary, the solution is defining ch
to be an int
instead of a char
.
Upvotes: 3