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?
Using %x format specifier in printf, we can print the hexadecimal values.
Printing the number in Hexadecimal format To print integer number in Hexadecimal format, "%x" or "%X" is used as format specifier in printf() statement. "%x" prints the value in Hexadecimal format with alphabets in lowercase (a-f). "%X" prints the value in Hexadecimal format with alphabets in uppercase (A-F).
unsigned char ch = 212 ; And your printf will work. Even with ch changed to unsigned char , the behavior of the code is not defined by the C standard. This is because the unsigned char is promoted to an int (in normal C implementations), so an int is passed to printf for the specifier %u .
In C programming language, we can use hexadecimal literals in any expressions; we can assign hexadecimal numbers to the variables. To use hexadecimal literals, we use 0X or 0x as a prefix with the number. For example 0x10 is a hexadecimal number, which is equivalent to 16 in the decimal number system.
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)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With