【问题标题】:Difference between scanf("%c", &c) and scanf(" %c", &c) [duplicate]scanf("%c", &c) 和 scanf("%c", &c) 之间的区别 [重复]
【发布时间】:2023-03-17 23:25:01
【问题描述】:

考虑以下 C 代码 sn-p:

#include <stdio.h>

int main()
{
    int a;
    char c;
    scanf("%d",&a);
    scanf("%c",&c);
    printf("int=%d\n",a);
    printf("char=%c\n",c);
}

我只能输入整数而不是字符。输出只是整数值,第二个 printf 语句不输出任何值。

但是,如果我在格式说明符之前使用空格:

scanf(" %c",&c);

它按预期工作。为什么会这样?

有人告诉我这与清除输入缓冲区有关。有人能解释一下吗?

【问题讨论】:

    标签: c scanf


    【解决方案1】:

    scanf("%c", &amp;c1)scanf(" %c", &amp;c2) 的区别在于,没有空格的格式会读取下一个字符,即使是空格,而有空格的格式会跳过空格(包括换行符)并读取下一个字符那不是空白。

    scanf() 格式中,空格、制表符或换行符表示“如果有要跳过的空格,请跳过空格”。它不会直接“清除输入缓冲区”,但它会吃掉任何看起来类似于清除输入缓冲区的空白(但与此完全不同)。如果您在 Windows 上,使用 fflush(stdin) 清除输入缓冲区(空白和非空白字符);在 Unix 上,根据 C 标准,fflush(stdin) 是未定义的行为。

    顺便说一句,如果您键入整数后紧跟回车,程序的输出将以两个换行符结束:第一个在c 中,第二个在格式字符串中。因此,您可能已经看到:

    $ ./your_program
    123
    int=123
    char=
    
    $
    

    也就是说,scanf() 读取换行符作为其输入。考虑另一种输入:

    $ ./your_program
    123xyz
    int=123
    char=x
    $
    

    整数输入在读取 'x' 时停止;因此,字符输入读取“x”。

    【讨论】:

    • 你能告诉我清除和跳过缓冲区的区别吗,我在这里很困惑?
    • 不同之处在于拼写——“ing”之前的五个字符。 “清除”或“跳过”没有明确的含义。我想如果我要选择一个含义,“清除”将使程序员参与一些明确的工作,而“跳过”发生在 scanf()-family 函数内部,程序员没有任何明确的工作,但这有待讨论和其他人可能有合法的替代定义,它们也可以连贯地工作。
    【解决方案2】:

    因为在你输入数字后按回车,新行留在缓冲区中,会被第二个scanf处理。

    简而言之,您在变量c 中保存了新行。

    但是,如果你使用

    scanf(" %c",&c);
    //     ^
    

    空间将占用新行,这使c 成为您期望的值。

    【讨论】:

      【解决方案3】:

      你必须传递一个指向格式字符串指定的数据对象的指针,所以

      scanf("%c", c);
      

      实际上会传递 c 的值,这反过来可能导致程序错误,

      scanf("%c", &c);
      

      将传递 c 的地址,允许 scanf 更改您的副本的值。

      %c 后面的空格会强制它查找一个字符,然后是一个空格。如果没有空格,则不会读取字符

      【讨论】:

      • 这甚至没有尝试回答为什么空间使scanf 正常工作的问题。除此之外,OP在问题中没有任何地方建议使用scanf("%c", c)
      • 另外,格式字符串中的尾随空格是一个小灾难,至少对于交互式程序来说是这样;直到它读取然后推回一个非空白字符才满足。因此,您可以输入 'x' 并返回,但 scanf("%c ", &amp;c) 不会返回,除非您输入除空格或制表符之外的其他内容。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-01-13
      • 1970-01-01
      • 2019-03-25
      • 1970-01-01
      相关资源
      最近更新 更多