By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
446,171 Members | 1,027 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 446,171 IT Pros & Developers. It's quick & easy.

Problem printing Hexadecimal

P: n/a
Hi,
I am trying to read an exe file and print it out character by
character in hexadecimal format. The file goes something like this in
hexadecimal
0x4d 0x5a 0x90 0x00 0x03 .... so on
When I read it into my array " two_bytes" which has 16 characters in
total, I get each of these values read correctly, but when I attempt
printing them out, it prints something like this:
0x4d 0x5a 0xffffff90 0x00 0x03 .... so on. I have no clue why. How can
I correct this

FILE *fp = NULL;
int count = 0;
char nibble = NULL;
char two_bytes[16];
int i;
fp = fopen("xyz.exe","r");
if(fp == NULL)
{
printf("Unable to Open file\n");
exit(0);
}
while(!feof(fp))
{
fscanf(fp,"%c",&two_bytes[count++]);
if(count % 16 == 0)
{
for(i=0; i<count ; i++)
printf("%#x ",two_bytes[i]);
printf(" || ");
for(i=0; i<count ; i++)
printf("%4c ",two_bytes[i]);
count = 0;
printf("\n");
}
}
fclose(fp);
return 0;

Mar 19 '07 #1
Share this Question
Share on Google+
14 Replies


P: n/a
ab************@gmail.com writes:
char two_bytes[16];
(...)
printf("%#x ",two_bytes[i]);
'char' can be signed. A negative char is promoted to int, and
%#x prints it as unsigned int, thus char 0x90 becomes 0xffffff90.

Use unsigned char two_bytes[16];
or printf("%#x ", (unsigned char) two_bytes[i]);

--
Regards,
Hallvard
Mar 19 '07 #2

P: n/a
In article <11*********************@n59g2000hsh.googlegroups. com>,
<ab************@gmail.comwrote:
I am trying to read an exe file and print it out character by
character in hexadecimal format. The file goes something like this in
hexadecimal
0x4d 0x5a 0x90 0x00 0x03 .... so on
When I read it into my array " two_bytes" which has 16 characters in
total, I get each of these values read correctly, but when I attempt
printing them out, it prints something like this:
0x4d 0x5a 0xffffff90 0x00 0x03 .... so on. I have no clue why. How can
I correct this
>FILE *fp = NULL;
int count = 0;
char nibble = NULL;
char two_bytes[16];
make two_bytes unsigned char
> int i;
fp = fopen("xyz.exe","r");
if(fp == NULL)
{
printf("Unable to Open file\n");
exit(0);
}
while(!feof(fp))
{
fscanf(fp,"%c",&two_bytes[count++]);
You've made a classic error there. feof() is not set until
you try and fail to read a character -- it does NOT "peek ahead"
to see whether the next read would fail or not. So you are going
to have to try to read the character and then determine whether
the read failed.

There is no good reason to fscanf with a single %c format:
see fgetc().
> if(count % 16 == 0)
{
for(i=0; i<count ; i++)
printf("%#x ",two_bytes[i]);
printf(" || ");
for(i=0; i<count ; i++)
printf("%4c ",two_bytes[i]);
Oh, you don't want to do that. What if it's a newline or a bell
or something like that?

You should first test that it's a printable character, and if
it is then you can putchar() it; if it isn't, then print
a placeholder instead ('.' is typical.)

Or instead of a placeholder, if it isn't important that the
text equivilent always be exactly the same length, you could
print a representation -- for example, the character pair
'\' 't' for tab, '\' 'b' for backspace. ^ followed by a letter
is a common representation for ASCII control characters.

That just leaves you with a choice of representations when
the character is above the ASCII printable range, such as if
it is 0xac ...
> count = 0;
printf("\n");
}
}
fclose(fp);
return 0;

--
Programming is what happens while you're busy making other plans.
Mar 19 '07 #3

P: n/a
Thank you !!! That fixed it. I realized I'd forgotten to make it a
"unsigned char"

On Mar 19, 5:13 pm, Hallvard B Furuseth <h.b.furus...@usit.uio.no>
wrote:
abhishekkar...@gmail.com writes:
char two_bytes[16];
(...)
printf("%#x ",two_bytes[i]);

'char' can be signed. A negative char is promoted to int, and
%#x prints it as unsigned int, thus char 0x90 becomes 0xffffff90.

Use unsigned char two_bytes[16];
or printf("%#x ", (unsigned char) two_bytes[i]);

--
Regards,
Hallvard

Mar 19 '07 #4

P: n/a
ab************@gmail.com wrote:
Thank you !!! That fixed it. I realized I'd forgotten to make it a
"unsigned char"
Please don't top-post. Your replies belong following or interspersed
with properly trimmed quotes. See the majority of other posts in the
newsgroup, or:
<http://www.caliburn.nl/topposting.html>
Mar 19 '07 #5

P: n/a
ab************@gmail.com wrote:
Hi,
I am trying to read an exe file and print it out character by
character in hexadecimal format. The file goes something like this in
hexadecimal
0x4d 0x5a 0x90 0x00 0x03 .... so on
When I read it into my array " two_bytes" which has 16 characters in
total, I get each of these values read correctly, but when I attempt
printing them out, it prints something like this:
0x4d 0x5a 0xffffff90 0x00 0x03 .... so on. I have no clue why.
Because the char is a small integer which can be positive or negative.
Before being used by printf, it is implicitly converted to a normal
integer. Every byte from 0x80 to 0xFF will be interpreted as a negative
number, and the print result is based on a four-byte-representation of
that number.
How can
I correct this

FILE *fp = NULL;
int count = 0;
char nibble = NULL;
char two_bytes[16];
Here: declare your bytes as unsigned char.

Good luck!

Tobias

Mar 19 '07 #6

P: n/a
In article <56*************@mid.individual.net>,
Default User <de***********@yahoo.comwrote:
>ab************@gmail.com wrote:
>Thank you !!! That fixed it. I realized I'd forgotten to make it a
"unsigned char"

Please don't top-post. Your replies belong following or interspersed
with properly trimmed quotes. See the majority of other posts in the
newsgroup, or:
<http://www.caliburn.nl/topposting.html>
Get a life!

Mar 19 '07 #7

P: n/a
On Mar 20, 9:19 am, rober...@ibd.nrc-cnrc.gc.ca (Walter Roberson)
wrote:
<abhishekkar...@gmail.comwrote:
char two_bytes[16];

make two_bytes unsigned char
fscanf(fp,"%c",&two_bytes[count++]);

There is no good reason to fscanf with a single %c format:
see fgetc().
Well, fgetc() returns a value in the range for unsigned char.
If he were still reading into a char, then using fgetc() would
cause implementation-defined behaviour due to out-of-range
assignment. However, fscanf with "%c" does not suffer that same
problem.
Mar 20 '07 #8

P: n/a
Old Wolf wrote:
>
On Mar 20, 9:19 am, rober...@ibd.nrc-cnrc.gc.ca (Walter Roberson)
wrote:
<abhishekkar...@gmail.comwrote:
char two_bytes[16];
make two_bytes unsigned char
fscanf(fp,"%c",&two_bytes[count++]);
There is no good reason to fscanf with a single %c format:
see fgetc().

Well, fgetc() returns a value in the range for unsigned char.
If he were still reading into a char, then using fgetc() would
cause implementation-defined behaviour due to out-of-range
assignment.
However, fscanf with "%c" does not suffer that same problem.
fgetc returns type int
and is capable of returning a negative value equal to EOF.

--
pete
Mar 20 '07 #9

P: n/a
In article <11**********************@o5g2000hsb.googlegroups. com>,
Old Wolf <ol*****@inspire.net.nzwrote:
>On Mar 20, 9:19 am, rober...@ibd.nrc-cnrc.gc.ca (Walter Roberson)
wrote:
> <abhishekkar...@gmail.comwrote:
char two_bytes[16];
>make two_bytes unsigned char
fscanf(fp,"%c",&two_bytes[count++]);
>There is no good reason to fscanf with a single %c format:
see fgetc().
>Well, fgetc() returns a value in the range for unsigned char.
If he were still reading into a char, then using fgetc() would
cause implementation-defined behaviour due to out-of-range
assignment.
You cannot "read into a char" when using fgetc(): you have
to assign its value to something. You would take the usual
precautions to assign to an int, check the value for EOF, and
only then assign from the int into the unsigned char.

>However, fscanf with "%c" does not suffer that same problem.
You would have to check the return value of fscanf(), which
is going to return EOF when the input ends. If you are prone
to make the mistake of assigning the return value to an unsigned
value for fgetc(), you are equally likely to be prone to assigning
the return value from fscanf() to an unsigned int.
--
Okay, buzzwords only. Two syllables, tops. -- Laurie Anderson
Mar 20 '07 #10

P: n/a
On Mar 20, 1:53 pm, rober...@ibd.nrc-cnrc.gc.ca (Walter Roberson)
wrote:
Old Wolf <oldw...@inspire.net.nzwrote:
Walter Roberson wrote:
There is no good reason to fscanf with a single %c format:
see fgetc().
Well, fgetc() returns a value in the range for unsigned char.
If he were still reading into a char, then using fgetc() would
cause implementation-defined behaviour due to out-of-range
assignment.

You cannot "read into a char" when using fgetc(): you have
to assign its value to something. You would take the usual
precautions to assign to an int, check the value for EOF, and
only then assign from the int into the unsigned char.
My comment was relating to the situation where you want to read
a value into a plain char. In that case, assigning from the int
to the char, on systems where plain char is signed, could cause
an out-of-range assignment problem.
However, fscanf with "%c" does not suffer that same problem.

You would have to check the return value of fscanf(), which
is going to return EOF when the input ends. If you are prone
to make the mistake of assigning the return value to an unsigned
value for fgetc(), you are equally likely to be prone to assigning
the return value from fscanf() to an unsigned int.
My original post was not concerned with error-checking. But if you
are to check for EOF then I think it is still much simpler in the
fscanf situation! The code with error-checking would have to be
something like:

int ch;
/* ... */
ch = fgetc(fp);
if ( ch == EOF )
break; /* or whatever */
two_bytes[count++] = ch;

vs.

if ( fscanf(fp, "%c", &two_bytes[count++]) )
break;

Furthermore, the first snippet still has the problem of out-of-range
assignment, which I don't see an easy way around.

(Of course the better solution to the original problem is to switch
to using unsigned char, in which case fgetc() becomes superior to
fscanf, no argument there).

Mar 20 '07 #11

P: n/a
In article <11*********************@n76g2000hsh.googlegroups. com>,
Old Wolf <ol*****@inspire.net.nzwrote:
>My original post was not concerned with error-checking. But if you
are to check for EOF then I think it is still much simpler in the
fscanf situation! The code with error-checking would have to be
something like:
int ch;
/* ... */
ch = fgetc(fp);
if ( ch == EOF )
break; /* or whatever */
two_bytes[count++] = ch;
>vs.
if ( fscanf(fp, "%c", &two_bytes[count++]) )
break;
>Furthermore, the first snippet still has the problem of out-of-range
assignment, which I don't see an easy way around.
Where do you see the possibility of an out of range assignment in
the first snippet? Unless two_bytes is defined as {signed} char --
but my commentary specifically said to define it as unsigned.
fgetc() will output EOF or an "unsigned char converted to int", so
unless your unsigned char has the same range as 0 to INT_MAX
you are going to be able to fit the converted value. But since unsigned
char may not have padding bits and int must have the signed range
available to it, int would have to be have a type larger than
0 to UCHAR_MAX, and we'd be getting into pathological cases
where sizeof(int) 1 but all the int bits (except the sign bit)
beyond those needed to hold UCHAR_MAX would have to be padding.
Maybe possible, but we're talking DS9K environments now.

if ( fscanf(fp, "%c", &two_bytes[count++]) )
break;
If fscanf() successfully reads a char in that snippet, then
it is going to return the number of input items successfully
matched, namely 1, so the if condition would be true.

If fscanf() encounters EOF then it is going to return EOF
which is guaranteed negative (and hence non-zero), and the
logical value of any negative number is true, so the if
condition would be true.

If the format item were nearly anything other than %c then
if characters were present but failed to match the format
spec then 0 items would be matched and the return value would
be 0 and the if condition there would be false. But %c cannot
fail to match a character if one is present, so that's not
going to happen.

Hence it would appear that you got the termination condition
on the fscanf() case wrong, which argues against your earlier
claim that it is easier to get the termination condition
right for fscanf() than for fgetc().
--
All is vanity. -- Ecclesiastes
Mar 20 '07 #12

P: n/a
On Mar 20, 6:11 pm, rober...@ibd.nrc-cnrc.gc.ca (Walter Roberson)
wrote:
Old Wolf <oldw...@inspire.net.nzwrote:
int ch;
/* ... */
ch = fgetc(fp);
if ( ch == EOF )
break; /* or whatever */
two_bytes[count++] = ch;
Furthermore, the first snippet still has the problem of out-of-range
assignment, which I don't see an easy way around.

Where do you see the possibility of an out of range assignment in
the first snippet? Unless two_bytes is defined as {signed} char
We are talking about the case where two_bytes is plain char,
and char is signed. As I pointed out in both of my previous
posts on this thread, there's no debate about the fact that
you should use fgetc when two_bytes is unsigned char.
if ( fscanf(fp, "%c", &two_bytes[count++]) )
break;

Hence it would appear that you got the termination condition
on the fscanf() case wrong, which argues against your earlier
claim that it is easier to get the termination condition
right for fscanf() than for fgetc().
Well, I could as easily have messed up the code for fgetc as I
did for fscanf! The correct version (ie. testing against 1) is
simpler than the correct version of fgetc.
Mar 21 '07 #13

P: n/a
Old Wolf wrote:
>
.... snip ...
>
Well, I could as easily have messed up the code for fgetc as I
did for fscanf! The correct version (ie. testing against 1) is
simpler than the correct version of fgetc.
fgetc returns EOF for any trouble, otherwise the integer
representation of an unsigned char.

--
Chuck F (cbfalconer at maineline dot net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net>

--
Posted via a free Usenet account from http://www.teranews.com

Mar 22 '07 #14

P: n/a
Groovy hepcat ab************@gmail.com was jivin' on 19 Mar 2007
14:04:50 -0700 in comp.lang.c.
Problem printing Hexadecimal's a cool scene! Dig it!
I am trying to read an exe file and print it out character by
character in hexadecimal format. The file goes something like this in
hexadecimal

FILE *fp = NULL;
int count = 0;
char nibble = NULL;
char two_bytes[16];
int i;
fp = fopen("xyz.exe","r");
In addition to what others have told you, you need to open the file
in binary mode.

--

Dig the even newer still, yet more improved, sig!

http://alphalink.com.au/~phaywood/
"Ain't I'm a dog?" - Ronny Self, Ain't I'm a Dog, written by G. Sherry & W. Walker.
I know it's not "technically correct" English; but since when was rock & roll "technically correct"?
Mar 24 '07 #15

This discussion thread is closed

Replies have been disabled for this discussion.