如何应对使用scanf时的非法输入

目录

具体代码如下( 仅供参考 )

背景:

报错原因:

清理输入缓冲区的方法和原因:

方法:

原因:

补充:


具体代码如下( 仅供参考 )

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

void menu() 
{
    printf("\n");
    printf(" 1->play \n");
    printf(" 0->exit \n");
    printf("\n");
}

// rand函数在使用前 要先使用srand函数来设置随机数的生成器
// 否则每次运行会生成相同的序列。
void game(void)
 {
    int num = rand() % 100 + 1;
    // rand生成的是伪随机数: 就是每一次重新运行是随机数的顺序是确定的
    // 比如第一次是生成的前三个是42 99 5 那重新启动时 前三个随机数依然时42 99 5达不到目的
    do {
        int input1;
        if (scanf("%d", &input1) != 1) 
        {
            printf("输入格式错误,请输入数字\n");
            // 清理输入缓冲区
            while (getchar() != '\n');
            continue;
        }
        if (input1 > num)
        {
            printf("猜大了 请重新输入->\n");
        } 
        else if (input1 < num)
        {
            printf("猜小了 请重新输入->\n");
        } else 
        {
            printf("恭喜你 猜对了正确答案是:%d\n\n\n", num);
            break;
        }
       } while (1);
}

int main() 
{
    int input;
    srand((unsigned int)time(NULL));
    // 在C语言中,srand() 函数用于初始化随机数生成器的种子
    // 只调用一次就够了 不然不够随机 连续快速输入两次可能会相同
    do 
    {
        menu();
        printf("请选择;\n");
        if (scanf("%d", &input) != 1)
       {
            printf("输入格式错误,请输入数字\n");
            // 清理输入缓冲区
            while (getchar() != '\n');
            continue;
        }
        switch (input)
        {
            case 1:
                printf("游戏开始\n");
                game();
                break;
            case 0:
                printf("退出游戏\n");
                break;
            default:
                printf("输入错误 请重新选择\n");
                break;
        }
     } while (input);

    return 0;
}    

背景:

在 C 语言里,scanf 函数是用于从标准输入(通常是键盘)读取格式化数据的。

当使用 scanf("%d", &input) 时,它期望用户输入一个整数。要是用户输入的是字母或者其他非数字字符,scanf 就无法把输入转换为整数,读取操作就会失败,并且这个非数字字符会留在输入缓冲区里。

若不清理输入缓冲区,后续的 scanf 调用会直接读取到这个留在缓冲区里的非数字字符,从而导致持续的读取失败,让程序陷入一种不符合预期的状态。(既导致进入无限循环)

报错原因:

当输入字母时,scanf 函数会因为格式不匹配而失败,并且会将字母留在输入缓冲区,从而导致后续的输入操作受到影响。为了让程序在输入字母时依旧可以返回循环,你需要清理输入缓冲区.

    清理输入缓冲区的方法和原因:

    方法:

    while (getchar() != '\n');
    

    getchar 函数的功能是从标准输入读取一个字符。这个循环会不断调用 getchar 函数,把输入缓冲区里的字符逐个读取出来,直到遇到换行符 '\n' 为止。换行符一般是用户按下回车键产生的,表示一次输入结束。

    原因:

    • 避免影响后续输入:当 scanf 读取失败时,非数字字符会留在输入缓冲区里。若不清理,后续的 scanf 调用会直接读取到这个非数字字符,导致持续的读取失败。

    • 确保程序正常运行:清理输入缓冲区可以让程序回到正常的输入等待状态,等待用户重新输入有效的数据。

    补充:

    • 清理输入缓冲区:while (getchar() != '\n');:这是用于清理输入缓冲区的代码。getchar 函数每次从输入缓冲区读取一个字符,这个循环会持续读取字符,直到遇到换行符 '\n' 为止,这样就能把输入缓冲区里的所有字符都清空。

    • 错误处理:在 game 函数和 main 函数中,当 scanf 读取失败时,输出错误信息并清理输入缓冲区,然后继续循环。

    • continue;:跳过本次循环的剩余部分,直接进入下一次循环,等待用户重新输入。

    • 通过清理输入缓冲区,就能保证程序在用户输入错误时也能稳定运行,持续等待用户输入正确的数据。

    评论
    添加红包

    请填写红包祝福语或标题

    红包个数最小为10个

    红包金额最低5元

    当前余额3.43前往充值 >
    需支付:10.00
    成就一亿技术人!
    领取后你会自动成为博主和红包主的粉丝 规则
    hope_wisdom
    发出的红包

    打赏作者

    阿方猛敲c嘎嘎

    你的鼓励将是我创作的最大动力

    ¥1 ¥2 ¥4 ¥6 ¥10 ¥20
    扫码支付:¥1
    获取中
    扫码支付

    您的余额不足,请更换扫码支付或充值

    打赏作者

    实付
    使用余额支付
    点击重新获取
    扫码支付
    钱包余额 0

    抵扣说明:

    1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
    2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

    余额充值