I am trying to convert a series of decimal numbers to their hex representation in string format and then back from string to decimal. This might sound strange but is a simplified representation of a more complex situation. So, either way, I have the following piece of code which almost works fine. For some reason my variable a is still equal to 0 at the end while it should equal 43, all the other variables seem to be alright:
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
/********************* A *******************/
uint16_t a = 43; //0x002b
int16_t b = -43; //0xffd5
uint32_t c = 234; //0x000000ea
int32_t d = -234; //0xffffff16
char aStr[10]={0};
char bStr[10]={0};
char cStr[10]={0};
char dStr[10]={0};
snprintf(aStr, sizeof(aStr), "%04hhx", a);
snprintf(bStr, sizeof(bStr), "%04x", b & 0xFFFF);
snprintf(cStr, sizeof(cStr), "%08hhx", c);
snprintf(dStr, sizeof(aStr), "%08x", d & 0xFFFFFFFF);
fprintf(stdout, "TX a = %s.\n", aStr);
fprintf(stdout, "TX b = %s.\n", bStr);
fprintf(stdout, "TX c = %s.\n", cStr);
fprintf(stdout, "TX d = %s.\n", dStr);
/********************* B *******************/
uint16_t aOut = 0;
int16_t bOut = 0;
uint32_t cOut = 0;
int32_t dOut = 0;
sscanf(aStr, "%04hhx", &aOut);
sscanf(bStr, "%04x", &bOut);
sscanf(cStr, "%08hhx", &cOut);
sscanf(dStr, "%08x", &dOut);
fprintf(stdout, "rx a = %d\n", aOut); //<---- this line prints 0 for a. Why?
fprintf(stdout, "rx b = %d\n", bOut);
fprintf(stdout, "rx c = %d\n", cOut);
fprintf(stdout, "rx d = %d\n", dOut);
return 0;
}
Does anybody know why or what I am missing?
The line
sscanf(aStr, "%04hhx", &aOut);
is wrong. The %hhx
conversion format specifier requires an argument of type unsigned char *
, but you are instead passing it an argument of type uint16_t *
. This invokes undefined behavior.
I suggest that you change that line to the following:
sscanf(aStr, "%04"SCNx16, &aOut);
On most platforms, the macro SCNx16
will simply expand to "hx"
, but it is generally safer to use the macro, in case you code happens to be running on a (future) platform on which uint16_t
is not equivalent to an unsigned short
.
The lines
sscanf(bStr, "%04x", &bOut);
sscanf(cStr, "%08hhx", &cOut);
sscanf(dStr, "%08x", &dOut);
are also using the wrong conversion format specifiers. I recommend that you use the following code instead:
sscanf(bStr, "%04"SCNx16, &bOut);
sscanf(cStr, "%08"SCNx32, &cOut);
sscanf(dStr, "%08"SCNx32, &dOut);
Strictly speaking, the above code also invokes undefined behavior, because the %x
conversion format specifier requires a pointer to an unsigned
type instead of to a signed
type. However, this should not be a problem in practice, provided that the converted value can be represented both in the signed
type and in the unsigned
type.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.