3

在下面的代码中,我想读取十六进制字符串“a”中的前 2 个字符,使用 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

编译器(代码中的 GNU GCC::Blocks):

[...]|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 行。此外,code::blocks 出于某种原因不喜欢 'h' 修饰符,即使 'b' 值已正确更新。

预期结果:

fa23456789abcdef
250
fa23456789abcdef

在这种情况下可以替代使用 strtol 吗?

4

2 回答 2

4

sscanf不支持hh,这意味着它正在转换为 anunsigned int并试图将其填充到unsigned char-sized 变量中,从而导致未定义的行为。在您的情况下,这显然意味着覆盖a. 修正你的警告!

如果你sscanf 确实支持hh,你会没事的,但你可能仍然应该更改achar数组而不是unsigned char.

您需要阅读本地sscanf文档以确定您应该传递什么,或者只是更改bunsigned int"%2x"用作您的格式字符串。

于 2013-08-30T20:32:30.240 回答
0

变量a应该是char,不是unsigned char。通过此更改,我的计算机中出现了预期的行为。

这是 sscanf 文档

于 2013-08-30T20:44:49.347 回答