Printing a hex value stored as a string gives an unexpected result

I have in C hexadecimal numbers defined in a string:

char chars[] = "\xfb\x54\x9c\xb2\x10\xef\x89\x51\x2f\x0b\xea\xbb\x1d\xaf\xad\xf8"; 

Then I want to compare the values ​​with others. It does not work, and if I print the value, for example:

 printf("%02x\n", chars[0]); 

he writes fffffffb . Why is this and how to get the fb value exactly?

+7
c string char printf hex
source share
3 answers

This is due to the expansion of the sign.

Edit

 printf("%02x\n", chars[0]); 

to

 printf("%02x\n", (unsigned char)chars[0]); 

The %x format %x will read 4 bytes on a 32-bit machine. Since you declared chars as an array of characters, when fb value fetch (negative value) will be expanded with a character like fffffffb , where the MSB from fb set before all other bits.

See expansion of a sign for more details.

If you declared char chars[] as unsigned char chars[] , then printing would be expected.

+6
source share

According to the standard mention of the %x format specifier with fprintf()

o,u,x,X

The unsigned int argument is converted to unsigned octal code ( o ), unsigned decimal ( u ), or unsigned hexadecimal notation (x or X) in the dddd style; [...]

So, the expected type of the argument %x is unsigned int .

Now that printf() is a variational function, only the default distribution rule is applied to its arguments. In your code, chars is an array of type char (the signature of which is implementation dependent), in the case of

 printf("%02x\n", chars[0]); 

the value of chars[0] gets promoted to int , which is not the expected type for %x . Therefore, the output is incorrect, since int and unsigned int are not the same type. [Cm. Β§6.7.2, C11 ]. So without explicit casting

 printf("%02x\n", (unsigned int)chars[0]); 

it causes undefined behavior .

FWIW, if you have a supported C99 compiler, you can use the hh length modifier to get around this, for example

  printf("%02hhx\n", (unsigned char)chars[0]); 
+2
source share

This is due to the expansion of the sign.

This will work as you expect:

 printf("%02x\n", (unsigned char)chars[0]); 
0
source share

All Articles