scanf无法扫描到uint8_t

时间:2014-05-19 22:32:13

标签: c

当我尝试将scanfuint8_t一起使用时,我会得到疯狂的结果。 使用int,我得到预期的输出" 08 - 15"。 使用uint8_t,我得到" 00 - 15"。

const char *foo = "0815";
uint8_t d1, d2; // output: 00 - 15 (!!!)
// int d1, d2;         // output: 08 - 15
sscanf(foo, "%2d %2d", &d1, &d2);
printf("%02d - %02d\n", d1, d2);

我正在使用GCC。

4 个答案:

答案 0 :(得分:7)

%d错误,因为这意味着您正在传递int *,但实际上您想要传递uint8_t *。您需要使用适当的宏:

#include <inttypes.h>
...
sscanf(foo, "%2" SCNu8 " %2" SCNu8, &d1, &d2);

大多数编译器应该为您提供有关您的代码版本的警告。这是Clang的输出:

test2.c:8:24: warning: format specifies type 'int *' but the argument has type
      'uint8_t *' (aka 'unsigned char *') [-Wformat]
sscanf(foo, "%2d %2d", &d1, &d2);
             ~~~       ^~~
             %2s
test2.c:8:29: warning: format specifies type 'int *' but the argument has type
      'uint8_t *' (aka 'unsigned char *') [-Wformat]
sscanf(foo, "%2d %2d", &d1, &d2);
                 ~~~        ^~~
                 %2s
2 warnings generated.

对于uint8_t,这不适用于printf(),因为uint8_t在传递给int之前始终会被提升为printf()。< / p>

答案 1 :(得分:4)

scanf格式说明符%d说“我保证会给你int *”。你不通过提供int的地址来打破这一承诺。所有赌注都已关闭。 (这是未定义的行为。)

道德:不要骗你的编译器。

答案 2 :(得分:0)

您的代码不起作用,因为当uint8_t只有一个字节时,您告诉scanf()期望指向4字节类型(int)的指针。

答案 3 :(得分:0)

#define __USE_MINGW_ANSI_STDIO 1 //or gcc prog.c -std=c99 -D__USE_MINGW_ANSI_STDIO

#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>

int main(){
    const char *foo = "0815";
    uint8_t d1, d2;
    sscanf(foo, "%2" SCNu8 "%2" SCNu8, &d1, &d2);
    printf("%02" PRIu8 " - %02" PRIu8 "\n", d1, d2);
    return 0;
}