I am trying to printout an unsigned char value as a 2-Digit hex value, but always getting the result as 4-Digit hex values, not sure what's wrong with my code.
// unsigned char declaration
unsigned char status = 0x00;
// printing out the value
printf("status = (0x%02X)\n\r", (status |= 0xC0));
I am expecting a 2 digit hex result as 0xC0
, but I always get 0xC0FF
.
As well, when I tried to print the same variable (status) as an unsigned char with the %bu
format identifier I got the output as 255
.
How do you get just the two hex characters as output?
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
.
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)
Cast it to unsigned char:
printf("status = (0x%02X)\n\r", (unsigned char)(status |= 0xC0));