C语言 循环中的scanf非法输入,类型错误,导致无限循环?

概述

又到了暴露自己无知的时候,今天用了scanf结果出现了如下bug。
如果不了解scanf的参数与返回值可以直接看这个 Microsoft Doc scanf
下面这段代码,如果输入正常整数的话,没有任何问题。但是,如果输入字符 f 会发生什么

int main(void){
    while (true) {
        int num = 0;
        printf("Please enter a number:");
        int out = scanf("%d", &num);
        printf("num is %d\n", num);
        printf("out is %d\n", out);
        if (num == 10) {
            break;
        }
    }
}

不卖关子了,如果本应该输入整型,你输了字母,那么会直接进入无限循环,终端那里疯狂出现那几行printf,而且scanf的返回值out会等于0,说明没有把输入的值匹配给num
那么为什么会突然无限循环呢,正常情况程序下应该会在下一个scanf那里停住,然后等着我输入下一个数
但是因为我开始输入了ff进入了一个叫缓冲队列的地方,如果这个缓冲队列里面不是空的,那么它会优先把已经在里面的元素分配给num,所以现在的情况是,缓冲队列非空,然后不断的出现scanf,类型匹配错误,开始运行下一条代码,所以进入了死循环。
那这种情况怎么解决呢?最好的办法是不用scanf,要不然很容易出现幺蛾子。如果但是单纯的让循环停下来,那么可以在后面加一个接受 %cscanf函数,这样子缓冲队列里面的元素就有地方出来了,循环开始正常运行。

int main(void){
    while (true) {
        int num = 0;
        char ch;
        printf("Please enter a number:");
        int out = scanf("%d", &num);
        printf("num is %d\n", num);
        printf("out is %d\n", out);
        if (num == 10) {
            break;
        }
        scanf("%c", & ch);
    }
}

像上面这样子就好了。


最后补充一下scanf的返回值

  • 如果成功,返回已成功转换和分配的字段数量,注意,有可能读取很多,但只分配了一部分
  • 如果如果format为 空 指针,则将调用无效参数处理程序,如 参数验证中所述。 如果允许执行继续,则这些函数将返回 EOF ,并将Errno 设置为EINVAL

你可能感兴趣的:(C语言 循环中的scanf非法输入,类型错误,导致无限循环?)