[英]Why does sscanf result in 0 in this case?
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:出于某种原因,我的变量 a 最后仍然等于 0,而它应该等于 43,所有其他变量似乎都没问题:
#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 *
. %hhx
转换格式说明符需要一个类型为unsigned char *
的参数,但您改为传递一个类型为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
.在大多数平台上,宏SCNx16
将简单地扩展为"hx"
,但使用宏通常更安全,以防您的代码碰巧在uint16_t
不等于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.严格来说,上面的代码也调用了未定义的行为,因为%x
转换格式说明符需要一个指向unsigned
类型而不是有signed
类型的指针。 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.但是,这在实践中应该不是问题,前提是转换后的值可以用有signed
类型和unsigned
类型表示。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.