【问题标题】:What is the behavior of scanf when using "%s" format specifier for reading in single char?使用“%s”格式说明符读取单个字符时,scanf 的行为是什么?
【发布时间】:2013-09-29 17:00:10
【问题描述】:
#include <stdio.h>

int main(void){

char a;
scanf("%s", &a);

return 0;
}

对我有用,但我想知道在其他情况下是否会出现任何意想不到的结果。

【问题讨论】:

  • 我会使用 getchar() 来做这个,可以肯定......我希望 scanf 不知道它得到什么样的地址,它会写入内存它不应该...
  • 标准非常明确地指出,混合错误的说明符和类型是未定义的行为。在任何任意背景下实践中发生的事情都是极其无趣且危险的。

标签: c scanf


【解决方案1】:

以这段代码为例——

#include <stdio.h>

int main(void){

    char a;
    char b = '1';
    char c = '1';
    scanf("%s", &a);

    printf("%c = %c\n", b, c);
    return 0;
}

您可能希望它打印1 = 1,但刚才我运行它时,它打印了= 1(至少在我的编译器中,不要期望它有任何稳定的东西)

scanf 将一个字符串写入 a 的地址,期望在那里分配足够的空间(在这种情况下这是错误的),该字符串具有输入字符和空终止符。在我的情况下,空终止符会覆盖其他一些内存 - b。这是未定义的行为 - 不要那样做(至少不要在期望它有意义的时候)。

【讨论】:

  • 谢谢,这正是我想知道的。我从不这样做,我只是想知道为什么编译器没有给出任何警告。
  • 我猜如果编译器看到传递给 scanf 的 char* 来自获取 char 变量的地址(而不是来自内存分配、数组或字符串文字),则可以实现警告,但这似乎是次要的事情,也可能是合法的(如果您定义 char str[N] 并通过 &(str[0]))
【解决方案2】:

使用%c 格式匹配单个char,或使用%s 匹配非空格字符的字符串。

将它们混合在一起(就像在您的代码中一样)是未定义的行为,任何事情都可能发生

【讨论】:

    猜你喜欢
    • 2010-11-03
    • 2020-07-26
    • 2020-04-13
    • 2013-05-19
    • 2011-01-10
    • 1970-01-01
    • 2012-07-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多