printf for a char in hex - why all the F's?

S

scrodchunk

I'm having a weird problem with printing bytes in hex format.

I have a bunch of print statements that are working okay, then using
the identical formatting later in my code I get some thing where the
formatting and type are ignored.

At one spot in my code I'm loading an array with random bytes

int i;
char byte_block[20];

for (i=0; i<20; i++)
byte_block = (char) rand()

then elsewhere:

for (i=0; i<20; i++)
printf(" heres a byte: %2.2X \n", byte_block);


rand() returns a random integer, but I'm casting it to a char, which
should give me a single byte
when I print out various elements of the array byte_block, I often get
a number much bigger than a byte (it's 4 bytes)

For some reason I get:

00 FFFFFFB3 77 FFFFFF82 FFFFFFAC 22 37 63 FFFFFFD6 74
77 FFFFFFBD FFFFFFED 09 30 FFFFFFC9 FFFFFFC4 FFFFFFE9 7C 61

(my extra cr/lfs)


Why are some prints nice 2 digit bytes and others have 6 F's? What am
I missing.
Elsewhere in my code I'm doing the same thing and get a nice string of
2digit bytes.

Even when I do this:

printf(" heres a byte: %2.2X \n", (char)byte_block[3]);
I get FFFFFF82. The format and the cast are being ignored??

Confused on a friday evening,

Ross
 
D

Drew MacDonald

scrodchunk said:
I'm having a weird problem with printing bytes in hex format.

I have a bunch of print statements that are working okay, then using
the identical formatting later in my code I get some thing where the
formatting and type are ignored.

At one spot in my code I'm loading an array with random bytes

int i;
char byte_block[20];

for (i=0; i<20; i++)
byte_block = (char) rand()


Try declaring byte_block as unsigned char.

When by casting to char you truncate and just get
the lowest order byte, which can contain any value from
0x00..0xFF. A positive char can be 0x00..0x7F.
0x80..0xFF represents negative numbers. printf is
interpreting the %2.2X as a signed integer and dealing
with it as such.

Hope this helps.
Drew
 
E

Eric Sosman

scrodchunk said:
I'm having a weird problem with printing bytes in hex format.

I have a bunch of print statements that are working okay, then using
the identical formatting later in my code I get some thing where the
formatting and type are ignored.

At one spot in my code I'm loading an array with random bytes

int i;
char byte_block[20];

for (i=0; i<20; i++)
byte_block = (char) rand()


Missing a semicolon, methinks.
then elsewhere:

for (i=0; i<20; i++)
printf(" heres a byte: %2.2X \n", byte_block);


rand() returns a random integer, but I'm casting it to a char, which
should give me a single byte
when I print out various elements of the array byte_block, I often get
a number much bigger than a byte (it's 4 bytes)

For some reason I get:

00 FFFFFFB3 77 FFFFFF82 FFFFFFAC 22 37 63 FFFFFFD6 74
77 FFFFFFBD FFFFFFED 09 30 FFFFFFC9 FFFFFFC4 FFFFFFE9 7C 61

(my extra cr/lfs)


Why are some prints nice 2 digit bytes and others have 6 F's? What am
I missing.


Consider the 128's bit in each of the above numbers.
Does a pattern emerge?
Elsewhere in my code I'm doing the same thing and get a nice string of
2digit bytes.

Even when I do this:

printf(" heres a byte: %2.2X \n", (char)byte_block[3]);
I get FFFFFF82. The format and the cast are being ignored??

Confused on a friday evening,

The `char' type may be signed or unsigned, at the
implementation's discretion: some implementations make
it unsigned and consider the values as running from zero
to 255 (or higher; `char' may be wider than 8 bits), while
others make it signed and think of the values as running
from -127 (or lower) to 127 (or higher). The commonest
variations are -128 <= `char' <= 127 or 0 <= `char' <= 255.

Your implementation is probably of the former type.
Now, what happens to a `char' value when you pass it to
a function like printf(), where the parameter type is not
specified? It gets promoted, most likely to `int' (but to
`unsigned int' on some unusual machines). And if you take
a `char' whose value is -42, say, what `int' value do you
get after the promotion? And what are the high-order bits
of that `int' value?

I'm tempted to suggest you use `unsigned char', but
I really don't know what you're trying to do. In any case
you're using rand() in a less-than-wonderful way; see
Question 13.16 in the comp.lang.c Frequently Asked Questions
(FAQ) list

http://www.eskimo.com/~scs/C-faq/top.html

to learn what's wrong with your method, and what to do
about it.
 
M

Martin Ambuhl

scrodchunk said:
I'm having a weird problem with printing bytes in hex format.

I have a bunch of print statements that are working okay, then using
the identical formatting later in my code I get some thing where the
formatting and type are ignored.

At one spot in my code I'm loading an array with random bytes

int i;
char byte_block[20];

for (i=0; i<20; i++)
byte_block = (char) rand()

then elsewhere:

for (i=0; i<20; i++)
printf(" heres a byte: %2.2X \n", byte_block);


rand() returns a random integer, but I'm casting it to a char, which
should give me a single byte
when I print out various elements of the array byte_block, I often get
a number much bigger than a byte (it's 4 bytes)

For some reason I get:

00 FFFFFFB3 77 FFFFFF82 FFFFFFAC 22 37 63 FFFFFFD6 74
77 FFFFFFBD FFFFFFED 09 30 FFFFFFC9 FFFFFFC4 FFFFFFE9 7C 61

(my extra cr/lfs)


Your chars appear to be signed. Note the added 'unsigned' below:

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
int i;
unsigned char byte_block[20]; /* mha: added 'unsigned' */
for (i = 0; i < 20; i++)
byte_block = (char) rand(); /* mha: added ';' */
for (i = 0; i < 20; i++)
printf(" heres a byte: %2.2X \n", byte_block);
return 0;
}
 
A

Al Bowers

scrodchunk said:
I'm having a weird problem with printing bytes in hex format.

I have a bunch of print statements that are working okay, then using
the identical formatting later in my code I get some thing where the
formatting and type are ignored.

At one spot in my code I'm loading an array with random bytes

int i;
char byte_block[20];

for (i=0; i<20; i++)
byte_block = (char) rand()

then elsewhere:

for (i=0; i<20; i++)
printf(" heres a byte: %2.2X \n", byte_block);


rand() returns a random integer, but I'm casting it to a char, which
should give me a single byte


There may be problems elsewhere, but there is a problem in the
assignment of return value of function rand, an int type, to a
char type. if the value returned by rand is too large to fit in
a type char, the result is unpredictable.

You can change the array to unsigned char type and assign a
value using the '%' operator,ie, byte_block = rand()%256.
You will have assurance that the value will be in the range of
0 - 255.

Example:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main(void)
{
unsigned i;
unsigned char byte_block[20];

srand((unsigned)time(NULL));
for (i=0; i<20; i++)
byte_block = rand()%256;
for (i=0; i<20; i++)
printf("A byte: (HEX) %2.2X (DECIMAL) %3u\n",
byte_block, byte_block);
return 0;
}
 
P

Pierre Maurette

(e-mail address removed) (scrodchunk) typa:
[...]
int i;
char byte_block[20];
(in addition to others answers)
I like to typedef the char according to its actual use, and the
typedef or #define of the implementation. For example:
typedef unsigned char byte;/* memory examination */
typedef unsigned char uint8;/* calculations, assuming 8 bits wide */
char just for ... characters.
 
O

Old Wolf

I'm having a weird problem with printing bytes in hex format.

char byte_block[20];
printf(" heres a byte: %2.2X \n", byte_block);

For some reason I get:

00 FFFFFFB3 77 FFFFFF82 FFFFFFAC 22 37 63 FFFFFFD6 74
77 FFFFFFBD FFFFFFED 09 30 FFFFFFC9 FFFFFFC4 FFFFFFE9 7C 61

"%x" and "%X" are only for printing 'unsigned int' values.
Passing a signed int to them is undefined behaviour. There is no
format specifier for printing signed values as hex.

Because printf() is variadic, its prototype can't specify the
type for the other parameters. In this case the rules of C state
that chars get promoted to 'signed int' (see the standard for a
list of other promotions and exceptions to this rule),
this is necessary in order for the variadic function mechanism to
work safely.
So if your char was negative then printf will receive a negative int.
Finally, with '%X' it was expecting an unsigned int, so probably
what will happen is that it will try and interpret the bit pattern
of your negative int as an unsigned int. On 2's complement machines
this actually works, so you will get the same display as if you went:
printf("%x", (unsigned int) foo);

If you want to print a value between 0..255 , you would have to
cast your char to an unsigned char before passing it to printf.
(Strictly speaking, I think it should be cast to unsigned char and
then to unsigned int, but in practice you never have to do this.)
 
D

Dan Pop

In said:
Op 25 Jun 2004 14:58:08 -0700 schreef scrodchunk:

char byte_block[20];
unsigned char byte_block[20];

In C a char usually is signed.

Except when it isn't.

The point is that, in C, plain char *may* behave like signed char and,
to avoid this possibility affecting your code, you use unsigned char
when you actually want to play with bytes.

Dan
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,145
Messages
2,570,824
Members
47,369
Latest member
FTMZ

Latest Threads

Top