在下面的代码中,我想读取十六进制字符串'a'中的前两个字符,用sscanf将它们转换为相应的字节值,并将结果放在'b'中。不应对'a'进行任何修改。
#include <stdio.h>
#include <string.h>
int main()
{
unsigned char a[]="fa23456789abcdef"; // 0-9 a-f
unsigned char b;
unsigned int idx = 0;
for(idx = 0; idx < 16; idx++)
printf("%c", a[idx]); // raw dump 'a'
printf("\n");
sscanf(a, "%2hhx", &b); // do sscanf
printf("%d\n", b); // check that 'b' has been correctly updated
for(idx = 0; idx < 16; idx++)
printf("%c", a[idx]); // raw dump 'a'... again
return 0;
}
输出:
fa23456789abcdef
250
3456789abcdef
编译器(Code :: Blocks中的GNU GCC):
[...]|14|warning: pointer targets in passing argument 1 of 'sscanf' differ in signedness [-Wpointer-sign]|
[...]stdio.h|348|note: expected 'const char *' but argument is of type 'unsigned char *'|
[...]|14|warning: unknown conversion type character 'h' in format [-Wformat]|
[...]|14|warning: too many arguments for format [-Wformat-extra-args]|
||=== Build finished: 0 errors, 3 warnings (0 minutes, 0 seconds) ===|
在输出中,'a'的前3个字符被3个空字符替换,没有明显的原因。所有警告都指向sscanf线。 此外,即使'b'值正确更新,code :: blocks由于某种原因也不喜欢'h'修饰符。
预期结果:
fa23456789abcdef
250
fa23456789abcdef
在这种情况下,是否可以使用strtol?
答案 0 :(得分:4)
您的sscanf
不支持hh
,这意味着它正在转换为unsigned int
并尝试将其填充到unsigned char
大小的变量中,从而导致未定义的行为。在你的情况下,这意味着显然会覆盖a
的一部分。修正你的警告!
如果您的sscanf
支持hh
,您可以,但您可能仍应将a
更改为char
数组而不是unsigned char
。
您需要阅读本地sscanf
文档以确定应该传递的内容,或者只需将b
更改为unsigned int
并使用"%2x"
作为格式字符串。
答案 1 :(得分:0)
变量a
应为char
,而不是unsigned char
。通过此更改,我在计算机中具有预期的行为。