有关于scanf防止错误输入的值。

一个我不太能理解的地方:我的程序以下:


#include "stdio.h"
#include "stdlib.h"

enum color {red,yellow,green,};
void f(enum color c){
    printf("%d\n", c);
}

int main(){
    enum color t = red;
    int i;
    
    /* recont: */
    while( !(scanf("%d", &t)) || (t < 0 || t>2 ) ){
        printf("输入错误,必须输入数字0 <= x <= 2\n\n");
        if ( !(scanf("%d", &t))){
            scanf("%*s");
        }
    }
    f(t);
    /*     //是否继续
    printf("输入1继续:");
    scanf("%d", &i);
    if (i == 1){
        goto recont;
    } */

    system("pause");
    return 0;
}

为了防止输入超出预期的数字,我用

  while( !(scanf("%d", &t)) || (t < 0 || t>2 ) )

来做这件事情,
理论上来说无论输入什么,只要输入的不是0~2之间的某个整数,都会输出“输入错误,必须输入数字0 <= x <= 2\n\n”
但是,很奇怪

1111//输入
输入错误,必须输入数字0 <= x <= 2

7979//输入
32//输入
输入错误,必须输入数字0 <= x <= 2

red//输入


red//输入
输入错误,必须输入数字0 <= x <= 2

1//输入
1
请按任意键继续. . .

这就是问题,只要我上一个输入是数字,我就需要随便输入一个值才能输入下一个值,
只有输入的是一个字符串的时候(“例如‘red‘’”),才能直接开始输入下一个值。
如何解决这一问题呢,我想达到输入错误的值之后打印“输入错误,必须输入数字0 <= x <= 2\n\n”之后立马开始下一次输出而不是输入一个值给不知道什么地方才能开始下一次输出。

使用一个while循环把scanf()读取后遗留在缓冲区的其他字符读走即可,修改如下:

参考链接:

 
#include "stdio.h"
#include "stdlib.h"
 
enum color {red,yellow,green,};
void f(enum color c){
    printf("%d\n", c);
}
 
int main(){
    enum color t = red;
    int i;
    
    /* recont: */
    while( !(scanf("%d", &t)) || (t < 0 || t>2 ) ){
        printf("输入错误,必须输入数字0 <= x <= 2\n\n");
        // https://blog.csdn.net/haoshaokang_/article/details/121593252
        while(getchar()!='\n') // 把scanf()读取后遗留在缓冲区的其他字符读走即可
            continue;
         
    }
    f(t);
    /*     //是否继续
    printf("输入1继续:");
    scanf("%d", &i);
    if (i == 1){
        goto recont;
    } */
 
    system("pause");
    return 0;
}

img

程序中使用了scanf("%d", &t)来读取输入的整数,但如果输入不是整数,scanf会返回0。因此while循环中的条件 !(scanf("%d", &t)) 可以检测到输入不是整数的情况。然而,scanf在读取不是整数的输入时会将这些字符留在输入缓冲区中,导致后续的scanf调用读取到这些非法字符。

为了解决这个问题,我们可以在while循环中加入scanf("%*s"),这样可以将输入缓冲区中的所有字符读取出来,并丢弃掉。这样就可以在检测到输入不是整数之后立即重新输入而不用输入一个值给不知道什么地方才能开始下一次输出。

因此在如下位置加入scanf("%*s")即可

if ( !(scanf("%d", &t))){
scanf("%*s");
}

解决方案:
可以在while循环内部添加一行代码:

if ( !(scanf("%d", &t))){
    scanf("%*s");
}

这行代码的作用是:当输入不是整数时,将输入的值跳过,这样就不会有“输入一个值给不知道什么地方”的情况了。