【问题标题】:Why is scanf stuck inside a while loop?为什么scanf卡在while循环中?
【发布时间】:2013-07-08 02:11:06
【问题描述】:

我在 while 循环中使用了 scanf()。

while(1)
{
    int input = 0;
    scanf("%d\n", &input);
    printf("%d\n", input);
}

当我运行这个程序并输入一个数字时,printf() 不会显示该数字,除非我再次输入另一个数字。为什么?

【问题讨论】:

  • 你为什么把\n 放在scanf 格式字符串中?你这样做的原因是什么?
  • 这个问题以前也出现过,但是我发现很难找到合适的副本。 Exiting a while loop at EOF using scanf in C 有同样的基本问题,格式字符串在数字转换周围有前导和尾随空格)。我适度确定它不是唯一的候选人。我不确定它是不是最好的候选人。

标签: c


【解决方案1】:

scanf 格式中的 \n 被解释为“任意数量的空白”。它会一直读取空格(空格、制表符或回车),直到遇到不是空格的内容。

【讨论】:

    【解决方案2】:

    由于输入格式中的尾随 \n,您会得到该行为。它寻找空白,并且不知道何时完成扫描空白,直到遇到非空白字符。不要在scanf()-family 格式字符串中添加尾随空格,除非您真的知道自己在做什么,或者您实际上并未处理用户输入(输入来自程序或文件或字符串)。

    请注意,您的代码应该检查来自scanf() 的返回值;如果遇到 EOF(或者,实际上,如果遇到非数字、非空白字符),它将完全进入无限循环。此外,像这样指定换行符不会强制每个输入行一个数字。用户可能会愉快地在一行中输入1 2 3 4 5 6 7 8 9 0,您的代码同样会愉快地循环循环 9 次,然后才会卡住。

    您也可以使用fgets()(或POSIX getline()) 读取一行输入,然后使用sscanf() 将读取的数据转换为数字。请注意,尾随的换行符是无害的。

    【讨论】:

      【解决方案3】:

      如果您查看scanf 的参考资料,您会看到:

      格式字符串由空白字符组成(格式字符串中的任何单个空白字符都会消耗输入中所有可用的连续空白字符)

      所以\n 将触发此效果,如果您不希望出现此行为,请忽略\n

      scanf("%d", &input);
      

      【讨论】:

        【解决方案4】:
        scanf("%d\n", &input);
        

        我通常只是跟随

        scanf("%d", &input);
        

        没有“\n”

        【讨论】:

        • 在输出中留下换行符的人是在 SO 上编程的麻烦之一。如果您希望输出及时出现,您应该在完成输出后输出一个换行符。这对于诊断输出具有双重重要性;在程序崩溃或挂起之前没有出现的诊断输出是没有意义的,并且没有用换行符完成的输出很可能不会出现。 (这个答案也与问题无关。)
        • 感谢您的评论,我认为带有 \n 的 scanf 不是必需的
        • 顺便说一句,我编辑了答案,我的意思是换行符可以输出,但不能输入:D
        • 正确。您的答案的原始版本仅提到printf(),其中输出中的换行符或多或少是必要的(并且您的答案没有解决问题中的问题)。您修改后的答案仅提及scanf() 基本上是目标。 (顺便说一句,您最多可以编辑 cmets 5 分钟。)
        • 不知道为什么错过了,所以不应该复制然后过去,也不应该偷懒一直打字:/
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-07-04
        • 1970-01-01
        • 2012-10-11
        • 1970-01-01
        • 1970-01-01
        • 2021-12-16
        • 2020-03-11
        相关资源
        最近更新 更多