为什么 scanf 会用 0 覆盖之前读取的无符号字符变量?

3

我尝试通过scanf读取多个unsigned char值时,发现了一些奇怪的错误。在第二次调用scanf时,第一个unsigned char变量会被覆盖为0。但是写成scanf(" %hhu", &second);将导致第二个unsigned char变量被覆盖。

#include <stdio.h>

int main(void){
    unsigned char first, second;
    printf("Type first unsigned char variable: ");
    scanf("%hhu", &first);
    printf("first = %hhu\n", first);
    printf("Type second unsigned char variable: ");
    scanf("%hhu", &second);
    printf("first = %hhu\n", first);
    printf("second = %hhu\n", second);
    return 0;
}

编译器详情:

gcc-core(gcc-5.1.0-tdm-1-core)

binutils(binutils-2.24-1-mingw32-bin)

mingwrt(mingwrt-3.20-2-mingw32-dev,mingwrt-3.20-2-mingw32-dll)

w32api(w32api-3.17-2-mingw32-dev)

附:使用%hu%u没有区别。


1
请问您能否指定您所使用的编译器版本以及传递给它的参数,例如优化级别等。 - j2ko
1
很可能第二个地址跟在第一个地址后面。所以 %hhu 可能被解释为 %hu。hhu 是 C99 的扩展,因此 j2ko 关于编译器版本的问题是有道理的。 - carveone
这只是一个没有特殊输入的mingw gnu gcc编译器。 - Mr. White
2
MinGW使用微软库,而微软C库可能仍然是C90而不是C99或更高版本,因此它可能无法正确处理hh大小修饰符。 - Jonathan Leffler
1
我可以确认,微软的格式函数实现不识别%hhu,但我没有Windows安装在面前,所以我无法测试。你可以尝试在second中写入65535,看看是否对两个变量都打印出255。如果是这样,结论就是你不能在Windows上使用scanf(或任何其它变体)读取unsigned char值。 - zneak
显示剩余6条评论
1个回答

2
您似乎使用的是旧版本的MinGW且存在漏洞。
相反,您可以使用mingw-w64。该项目的分支部分原因是原始项目不愿意修复这种错误,而更喜欢责怪其他方面。
一旦使用该编译器,请使用-D__USE_MINGW_ANSI_STDIO编译器开关以获得符合模式(不幸的是,它仍默认为Microsoft兼容模式)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接