c - 为什么 scanf() 在此代码中导致无限循环?

标签 c gcc scanf

我有一个小的 C 程序,它只从标准输入读取数字,每个循环周期读取一个数字。如果用户输入了一些 NaN,则应该向控制台打印一个错误,并且应该再次返回输入提示。输入“0”时,循环应该结束,给定的正/负值的数量应该打印到控制台。这是程序:

#include <stdio.h>

int main()
{
    int number, p = 0, n = 0;

    while (1) {
        printf("-> ");
        if (scanf("%d", &number) == 0) {
            printf("Err...\n");
            continue;
        }
        
        if (number > 0) p++;
        else if (number < 0) n++;
        else break; /* 0 given */
    }

    printf("Read %d positive and %d negative numbers\n", p, n);
    return 0;
}

我的问题是,在输入一些非数字(如“a”)时,这会导致无限循环一遍又一遍地写入“-> Err ...”。我想这是一个 scanf() 问题,我知道这个函数可以用更安全的函数代替,但这个例子是为初学者准备的,只了解 printf/scanf、if-else 和循环。

我已经阅读了问题 scanf() skips every other while loop in C 的答案并浏览了其他问题,但没有真正回答这个具体问题。

最佳答案

scanf 仅消耗与格式字符串匹配的输入,返回消耗的字符数。任何与格式字符串不匹配的字符都会导致它停止扫描并将无效字符留在缓冲区中。正如其他人所说,在继续之前,您仍然需要从缓冲区中清除无效字符。这是一个非常肮脏的修复,但它会从输出中删除有问题的字符。

char c = '0';
if (scanf("%d", &number) == 0) {
  printf("Err. . .\n");
  do {
    c = getchar();
  }
  while (!isdigit(c));
  ungetc(c, stdin);
  //consume non-numeric chars from buffer
}

编辑:修复了一次性删除所有非数字字符的代码。不再为每个非数字字符打印出多个“错误”。

Here是对 scanf 的一个很好的概述。

关于c - 为什么 scanf() 在此代码中导致无限循环?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41393720/

相关文章:

c - malloc-ing C 中具有结构作为元素的结构?

c - CMX ColdFire USB-Lite 堆栈的文档

c++ - 是否可以在编译时将 gcc 编译标志检测为宏?

c - 我无法将十六进制值扫描到 C 中的数组中

c - 如何从 C 文件中查找某个字符的编号?

c++ - 将 C++ 成员函数分配给 C 函数指针

c - 运行没有缓存的程序

c - 对 _mm_crc32_u64 的 undefined reference

c - 使用 objdump/readelf 和 extern 变量

c - 用于读取数据库的损坏的 C 代码