How to print unsigned char as 2-digit hex value in C?

you are sending a char to a format string which expects an int. The printf function is grabbing another byte off the stack to fill it out. Try

 printf("%02X",(int)(status|0xC0));

Looking at all the answers, I think probably we are missing another way of doing this.

const unsigned char chararr[]="abceXYZ";
for (int i=0; i< 7; ++i) {
    printf("%#04X %d %c\n", chararr[i], chararr[i], chararr[i]);
}
0X61 97 a
0X62 98 b
0X63 99 c
0X65 101 e
0X58 88 X
0X59 89 Y
0X5A 90 Z

If you use %#04x small x then the output will b 0x small x prefix. The # pound sign tells the function to print the 0x. 04 to instruct how many digits to output, if input is '0x0a' it will print this,without 04 it will print '0xa'.

In my computer, Dell workstation, the output is as expected by the question. Unless

unsigned char status = 0x00;
printf("status = (0x%02X)\n\r", (status |= 0xC0));
// output
//status = (0xC0)
// is exactly expected by the original question. 

Better illustrated by examples:

 37    printf("status = (%#02x)\n", (status |= 0xC0));
 38    printf("status = (%#04x)\n", (status |= 0xC0));
 39    printf("status = (%#04x)\n", 0x0f);
 40    printf("status = (%#02x)\n", 0x0f);
status = (0xc0)
status = (0xc0)
status = (0x0f)
status = (0xf)

As far as I know, the Keil C compiler doesn't fully conform to the C standard. If so, it's likely that it doesn't quite follow the standard promotion rules for things like passing char values to variadic functions; on an 8-bit CPU, there are performance advantages in not automatically expanding 8-bit values to 16 bits or more.

As a workaround, you can explicitly truncate the high-order bits before passing the argument to printf. Try this:

#include <stdio.h>

int main(void) {
    unsigned char status = 0x00;
    status |= 0xC0;

    printf("status = 0x%02X\n", (unsigned int)(status & 0xFF));
    return 0;
}

Doing a bitwise "and" with 0xFF clears all but the bottom 8 bits; casting to unsigned int shouldn't be necessary, but it guarantees that the argument is actually of the type expected by printf with a "%02X" format.

You should also consult your implementation's documentation regarding any non-standard behavior for type promotions and printf.

Tags:

C

Keil