I have this part of code in C class:
int i;
for (i=0;i<val;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.
Quick and easy:
print("%x", (int)(rec->payload[i]));
To display in the format 0x05 then use:
print("0x%02x", ...)
instead.
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
Use "%x", so:
mdl_print ("%x ", rec->payload[i]);
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.
Note that providing a uint8_t or int where an unsigned int is expected in printf is undefined behaviour, as stated by section 7.21.6.1p9 of n1570.pdf: "If any argument is not the correct type for the corresponding conversion specification, the behavior is undefined." According to 7.21.6.1p8, %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;
}
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:
0xA6
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
Related
pixel_data is a vector of char.
When I do printf(" 0x%1x ", pixel_data[0] ) I'm expecting to see 0xf5.
But I get 0xfffffff5 as though I was printing out a 4 byte integer instead of 1 byte.
Why is this? I have given printf a char to print out - it's only 1 byte, so why is printf printing 4?
NB. the printf implementation is wrapped up inside a third party API but just wondering if this is a feature of standard printf?
You're probably getting a benign form of undefined behaviour because the %x modifier expects an unsigned int parameter and a char will usually be promoted to an int when passed to a varargs function.
You should explicitly cast the char to an unsigned int to get predictable results:
printf(" 0x%1x ", (unsigned)pixel_data[0] );
Note that a field width of one is not very useful. It merely specifies the minimum number of digits to display and at least one digit will be needed in any case.
If char on your platform is signed then this conversion will convert negative char values to large unsigned int values (e.g. fffffff5). If you want to treat byte values as unsigned values and just zero extend when converting to unsigned int you should use unsigned char for pixel_data, or cast via unsigned char or use a masking operation after promotion.
e.g.
printf(" 0x%x ", (unsigned)(unsigned char)pixel_data[0] );
or
printf(" 0x%x ", (unsigned)pixel_data[0] & 0xffU );
Better use the standard-format-flags
printf(" %#1x ", pixel_data[0] );
then your compiler puts the hex-prefix for you.
Use %hhx
printf("%#04hhx ", foo);
Then length modifier is the minimum length.
Width-specifier in printf is actually min-width. You can do printf(" 0x%2x ", pixel_data[0] & 0xff) to print lowes byte (notice 2, to actually print two characters if pixel_data[0] is eg 0xffffff02).
I am coding a C code and I want to compare the hexadecimal value of some character with an other. That is working, but with somme value like � I obtained a value on 4 bytes which create a no sense in my comparaison.
void obs_text(char* start, unsigned char debugLevel, unsigned char depth){
printf("%c -> 0x%x\n", start[0], start[0]);
}
I expected an output with two hexadecimals characters but the actual output is ? -> 0xffffffef.
Please does any one understand what happens ? Thank you for your help.
I am compiling with gcc.
Configured with: --prefix=/Library/Developer/CommandLineTools/usr --with-gxx-include-dir=/Library/Developer/CommandLineTools/SDKs/MacOSX10.14.sdk/usr/include/c++/4.2.1
Apple LLVM version 10.0.1 (clang-1001.0.46.3)
Target: x86_64-apple-darwin18.2.0
Thread model: posix
but I also try on a Debian OS with the same problem
Because %x means display as an unsigned integer (4 bytes) as hexadecimal. See http://www.cplusplus.com/reference/cstdio/printf/
As noted there, you could use %hhx (added in C99) to get the behavior you were expecting (see more in this answer).
Use %hhx and cast the argument to unsigned char:
printf( "%c - 0x%hhx", start[0], (unsigned char) start[0] );
%x expects its corresponding argument to have type unsigned int. You need to use the hh length modifier to tell it that you're dealing with an unsigned char value.
I have code running in 2 projects/platforms. It works in one, not the other. Code is like this:
uint8_t val = 1;
uint8_t buff[16];
sprintf(buff, "%u", val);
The expected output is "1" (gcc) but on one compiler (Keil) it returns "511", which in hex is 0x1FF. Looks like its not promoting the byte to int with this compiler. This is confirmed because it works ok if I do this:
sprintf(buff, "%u", (int)val);
My question is this: why does one compiler do what I consider the 'right thing', and one does not? Is it my incorrect expectations/assumptions, a compiler setting, or something else?
For maximum portability, you can use these macros from inttypes.h: (there are others)
PRId8, PRIx8, PRIu8
PRId16, PRIx16, PRIu16
PRId32, PRIx32, PRIu32
Normally (as I expected):
#define PRIu8 "u"
But for the Keil compiler in this case:
#define PRIu8 "bu"
e.g.,
printf("0x%"PRIx8" %"PRIu16"\n", byteValue, wordValue);
That's pretty cumbersome though. I suggest more friendly compilers.
It's amazing what you don't know about this stuff even after doing it for decades.
Your assumption may be correct, or incorrect. It depends on the compiler implementation. All modern (or should say smart) compiler will do that like you mentioned. But Keil, as of ver. 9.02, you need to specify correct variable length for printf.
This is Keil C's way handling all kinds of printf functions.
You need to specify exactly how long it is. All regular are for 16-bit (unsigned) integer including %d, %x, and %u. Use modifier 'b' for 8-bit and 'l' for 32-bit. If you gave wrong length, you would get wrong number. Even worse, the rest of the variables are all wrong.
For example, to use 8-bit 'char', you use '%bd' (%bu, and %bx), and %ld, %lu, and %lx for 32-bit 'long'.
char c = 0xab;
printf("My char number is correctly displayed as '0x%02bx'\n", c);
Also note, likewise, to get numeric data from sscanf, it's same. The following example is to get a 32-bit long variable using sscanf:
long var;
char *mynum = "12345678";
sscanf(mynum, "%ld", &var);
Variable var contains number 12345678 after sscanf.
Hereunder shows the length for variables used in printf family for Keil.
%bd, %bx, %bu - should be used for 8-bit variables
%d, %x, %u - should be used for 16-bit variables, and
%ld, %lx, %lu - should be used for 32-bit variables
I just started programming in C. And I don't really understand the following code:
printf("%zu",i);
or instead of %zu what are the other things that I can write (I know that they depend on the type of i) and which one is for what?
It's a format modifier for siz_t and size_t is unsigned.
printf("%zu\n", x); // print unsigned decimal
printf("%zx\n", x); // print hexadecimal
printf("%zd\n", y); // print signed decimal
It takes unsigned size_t i and prints it to the stdout.
I've just started reading C and have a question about a macro.
How can I print a 5 byte integer value (that happens to be defined in a macro)?
For example:
#define MAX 0xdeadbeaf12
int main(){
printf(" 0x %2x \n", MAX);
}
This code prints adbeaf12 but not deadbeaf12.
How do I get all the bytes printed?
I prefer to make my assumptions about the size of a variable explicit. The following uses standard (though often unused) macros to define a 64-bit constant and print such a quantity as a hex value.
#include <stdio.h>
// Pull in UINT64_C and PRIx64 macros
#include <inttypes.h>
// Make this a 64-bit literal value
#define MAX UINT64_C(0xdeadbeaf12)
int main()
{
// Use PRIx64 which inserts the correct printf specifier for
// a hex format of a 64-bit value
printf(" 0x%" PRIx64 " \n", MAX);
}
#define MAX 0xdeadbeaf12LL
Will tell the compiler to use the longest available integer type (which will then be cast to an appropriate type wherever MAX is used).
On most platforms, the numeric literal suffix LL will correspond to signed long long, this is 64bit (8 bytes) on a 32 bit system. C's excellent typing system and compiler warnings will take care of the rest for you.
Your printf then needs to use the ll modifier:
printf(" 0x %2llx \n", MAX);