【问题标题】:Why is scanf("%hhu", char*) overwriting other variables when they are local?为什么 scanf("%hhu", char*) 在本地时会覆盖其他变量?
【发布时间】:2013-04-05 03:08:33
【问题描述】:

标题说明了一切。 我正在使用 GCC 4.7.1(与 CodeBlocks 捆绑)并且遇到了一个奇怪的问题。考虑一下:

int main() {
    unsigned char a = 0, b = 0, c = 0;
    scanf("%hhu", &a);
    printf("a = %hhu, b = %hhu, c = %hhu\n", a, b, c);
    scanf("%hhu", &b);
    printf("a = %hhu, b = %hhu, c = %hhu\n", a, b, c);
    scanf("%hhu", &c);
    printf("a = %hhu, b = %hhu, c = %hhu\n", a, b, c);
    return 0;
}

对于输入 1、2 和 3,此输出

a = 1, b = 0, c = 0
a = 0, b = 2, c = 0
a = 0, b = 0, c = 3

但是,如果我将 a、b 和 c 声明为全局变量,它将按预期工作。 为什么会这样?

提前谢谢你

其他细节:

我正在运行 Windows 8 64 位。我也尝试了 -std=c99 并且问题仍然存在。

进一步研究

测试这段代码

void printArray(unsigned char *a, int n) {
    while(n--)
        printf("%hhu ", *(a++));
    printf("\n");
}

int main() {
    unsigned char array[8];
    memset(array, 255, 8);
    printArray(array, 8);
    scanf("%hhu", array);
    printArray(array, 8);
    return 0;
}

表明 scanf 将“%hhu”解释为“%u”。它直接忽略了“hh”。输入为 1 的代码输出为:

255 255 255 255 255 255 255 255
1 0 0 0 255 255 255 255

【问题讨论】:

  • 正在打印带有unsigned char UB 说明符的char
  • @Armin char 默认是无符号的,不是吗?
  • 不,这取决于平台。我无法重现您的结果。
  • @Armin 还有哪些有用的细节?我正在使用 Windows .. 我没有触及 CodeBlocks 中 GCC 的默认参数。顺便说一句,将变量明确声明为 unsigned char 并不能解决我的问题:S
  • 虽然主题与提议的副本相似,但这里的讨论比副本中的讨论要好 — 特别是,这里的答案强调 MSVC 运行时是 C89 而不是 C99,因此使用 C99表示法不能可靠地工作。

标签: c gcc gcc4.7


【解决方案1】:

重要的细节是您使用的是 Windows,并且可能是过时或不符合标准的 C 环境(编译器和标准库)。 MSVCRT 仅支持 C89(即便如此,也不完全正确);特别是,C89 中没有“hh”修饰符,它可能将“hh”解释为与“h”相同(即short)。

【讨论】:

  • 将所有 %hhu 更改为 %hu 确实与 OP 发布的完全一样。
  • 这更多是标准库的问题,而不是编译器的问题。如果 OP 的 gcc 正在使用 MSVCRT(如果它是“mingw”,情况就是这样),那么这绝对是问题所在。如果你想在 Windows 上做现代 C,目前唯一可行的选择是 Cygwin。
  • 我认为 CodeBlocks 包使用了 MinGW。我在切换或更新我的环境方面没有问题,我只是对这种行为感到好奇。我应该认为这是一个错误吗?
  • @DanielCastro:只是提供你scanf()的微软C标准库只支持C89,不包括hh修饰符。
  • 只是为了澄清。我想我以前做错了一些测试。将 %hu 与 unsigned char* 一起使用,尽管 UB 会覆盖预期的两个字节。 %hhu 被 MSVCRT 解释为 %u。
猜你喜欢
  • 2019-07-12
  • 1970-01-01
  • 2013-03-26
  • 2021-12-27
  • 1970-01-01
  • 2020-03-13
  • 2021-11-28
  • 2022-07-14
  • 2019-03-06
相关资源
最近更新 更多