猿问

为什么scanf()会在这段代码中导致无限循环?

为什么scanf()会在这段代码中导致无限循环?

我有一个小的C-程序,它只读取stdin的数字,每个循环一个。如果用户输入了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-ell和循环。

我已经读过答案了这个问题并略过其他问题,但没有真正回答这个具体的问题。


茅侃侃
浏览 933回答 3
3回答

PIPIONE

scanf只使用与格式字符串匹配的输入,返回所使用的字符数。任何不匹配格式字符串的字符都会导致其停止扫描,并将无效字符留在缓冲区中。正如其他人所说,在继续之前,仍然需要从缓冲区中清除无效字符。这是一个非常脏的修复,但它将从输出中删除违规字符。char&nbsp;c&nbsp;=&nbsp;'0';if&nbsp;(scanf("%d",&nbsp;&number)&nbsp;==&nbsp;0)&nbsp;{ &nbsp;&nbsp;printf("Err.&nbsp;.&nbsp;.\n"); &nbsp;&nbsp;do&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;c&nbsp;=&nbsp;getchar(); &nbsp;&nbsp;} &nbsp;&nbsp;while&nbsp;(!isdigit(c)); &nbsp;&nbsp;ungetc(c,&nbsp;stdin); &nbsp;&nbsp;//consume&nbsp;non-numeric&nbsp;chars&nbsp;from&nbsp;buffer}编辑:修正了一次删除所有非数字字符的代码.不再为每个非数字字符打印多个“错误”。这里是扫描的一个很好的概述。

牛魔王的故事

scanf()离开“a“下一次仍在输入缓冲区中。getline()无论如何读取一行,然后用strtol()或者类似的。(是的,getline()是GNU特有的,不是POSIX。那又怎么样?问题是“GCC”和“Linux”。getline()也是阅读一行文本的唯一明智选择,除非您想手动完成所有操作。)
随时随地看视频慕课网APP
我要回答