You can use hh
to tell printf
that the argument is an unsigned char. Use 0
to get zero padding and 2
to set the width to 2. x
or X
for lower/uppercase hex characters.
uint8_t a = 0x0a;
printf("%02hhX", a); // Prints "0A"
printf("0x%02hhx", a); // Prints "0x0a"
Edit: If readers are concerned about 2501's assertion that this is somehow not the 'correct' format specifiers I suggest they read the printf
link again. Specifically:
Even though %c expects int argument, it is safe to pass a char because of the integer promotion that takes place when a variadic function is called.
The correct conversion specifications for the fixed-width character types (int8_t, etc) are defined in the header
<cinttypes>
(C++) or<inttypes.h>
(C) (although PRIdMAX, PRIuMAX, etc is synonymous with %jd, %ju, etc).
As for his point about signed vs unsigned, in this case it does not matter since the values must always be positive and easily fit in a signed int. There is no signed hexideximal format specifier anyway.
Edit 2: ("when-to-admit-you're-wrong" edition):
If you read the actual C11 standard on page 311 (329 of the PDF) you find:
hh: Specifies that a following
d
,i
,o
,u
,x
, orX
conversion specifier applies to asigned char
orunsigned char
argument (the argument will have been promoted according to the integer promotions, but its value shall be converted tosigned char
orunsigned char
before printing); or that a followingn
conversion specifier applies to a pointer to asigned char
argument.