Take the 2-minute tour ×

I have this part of code in C class:

int i;
        mdl_print ("%u ", rec->payload[i]);
    mdl_print ("\n");

Variable rec->payload is uint8_t type. I would print it in hexadecimal notation.

How can I do? Thanks.

share|improve this question
presumably mdl_print() takes any format string that printf() takes? –  Mike Mar 11 '13 at 11:34
yes ;) I rewritten for my personal use –  sharkbait Mar 11 '13 at 11:48
I don't see how this question warrants a down-vote. It's not all that clear how to correctly convert uintN_t to strings of decimal digits, as evidenced by the number of incorrect answers to this question. How many answers were written by people who have read p8 and p9? Evidently, none. –  undefined behaviour Mar 11 '13 at 12:19
add comment

5 Answers

up vote 0 down vote accepted

First your title is so wrong... Casting integer to hex in C casting implies a type change, hex is a number system not a type. You're "displaying an integer in hex" not "casting". If you don't understand the difference please ask for clarification.

As far as the displaying goes, it depends what you want the result to look like. One short cut that I typically use is:

mdl_print("%#x ", rec->payload[i]);

Which displays values as:


The caveat on this syntax is that it doesn't work with 0, you don't get 0x0 just 0. So an alternative would be:

mdl_print("0x%x ", rec->payload[i]);

Which will display the value as 0xA6 or 0x0 or whatever it maybe. Of course if you don't want the 0x part you can always just do:

mdl_print("%x ", rec->payload[i]);

Your max value (in hex) with a unsigned 8-bit number is 0xFF so if you want them all to display the same "width" you can use the size specifier too:

mdl_print("%02x ", rec->payload[i]); // or mdl_print("0x%02x, rec->payload[i]); 
                                     // or whatever you picked
share|improve this answer
add comment

Quick and easy:

print("%x", (int)(rec->payload[i]));

To display in the format 0x05 then use:

print("0x%02x", ...)


share|improve this answer
add comment

If mdl_print() works like the standard C function printf(), try something like the following:

printf( "%02x", (int) rec->payload[i] );

The basic printf formatting code for writing in hexadecimal is %x. "02" means to pad the number with '0' until it's two characters wide, which is how you'd normally print an int8.

Many custom output functions follow the format of printf in this way, since it's very familiar to C programmers. You can read more about printf on its man page: http://linux.die.net/man/3/printf

share|improve this answer
the x format expects an unsigned int –  Jens Gustedt Mar 11 '13 at 12:43
add comment

Use "%x", so:


This will give you a hex number that is the "length necessary". If you want a fixed length, use "%02x" for two digits padded with zeros.

share|improve this answer
The argument should be explicitly converted to an unsigned int, if it functions anything like formatted printing in standard C: mdl_printf("%x", (unsigned int) rec->payload[i]);. Proof from of n1570.pdf: "The unsigned int argument is converted to ... unsigned hexadecimal notation (x or X)". –  undefined behaviour Mar 11 '13 at 11:58
add comment

Note that providing a uint8_t or int where an unsigned int is expected in printf is undefined behaviour, as stated by section of n1570.pdf: "If any argument is not the correct type for the corresponding conversion specification, the behavior is undefined." According to, %x tells printf to expect an unsigned int. Make sure you explicitly cast your uint8_t to (unsigned int), or use the PRIx8 macro found in <stdint.h>.

#include <assert.h>
#include <stdint.h>
#include <stdio.h>

int main(void) {
    uint8_t foo = 42;
    /* These two printfs are equivalent: */
    printf("Hex for %02u: %02x\n", (unsigned int) foo, (unsigned int) foo);
    printf("Hex for %02" PRIu8 ": %02" PRIx8 "\n", foo, foo);
    return 0;
share|improve this answer
Read section 7.20 (Integer types) of the same document. A uint8_t is a valid integer type and thus does not lead to UB –  Mike Mar 11 '13 at 12:30
@Mike, when put as such an unit8_t is converted to an int and not an unsigned, so 'modifiable lvalue' is correct that one should take care of that. –  Jens Gustedt Mar 11 '13 at 12:41
@JensGustedt ok, could you or modifiable lvalue then explain that a little further. 7.21.6 p8 says x takes an unsigned int argument. &3) states that a typedef name uintN_t designates an unsigned int type and the implementation provides 8 bits as one of the widths. So how is it that a uint8_t is not an unsigned int? Where is the conversion to signed int noted? and that an explicit typecast solves this? –  Mike Mar 11 '13 at 12:57
for implicit conversion all narrow types are converted to int as long as all values fit into it. BTW, this conversion is applied whenever a narrow type is used in an arithmetic expression or passed to a function without prototype (such as printf). –  Jens Gustedt Mar 11 '13 at 13:08
@Mike mentions "unsigned integer type", not "unsigned int". 7.21.6p8 specifically mentions "unsigned int". Is sizeof (uint8_t) == sizeof (unsigned int)? No. implies that integer promotions are applied to arguments of function calls like printf. "If an int can represent all values of the original type (as restricted by the width, for a bit-field), the value is converted to an int; ..." so the argument is actually an int. –  undefined behaviour Mar 11 '13 at 23:40
add comment

Your Answer


