c语言清空输入缓冲区


void Addition()
{
    int x, y, z, answer;
    int i;
    int wrong_answers = 5; //初始化为3,表示最多允许答错5int correct = 0; //用来存储用户答对的次数,初始为0 
    srand((unsigned)time(NULL));//生成随机数
    while (true){
        for (i = 1; i <= 30;i++){//输出30道加减乘除运算题
        x=rand()%100+1;
        y=rand()%100+1;
        gotoxy(FrameX+7,FrameY+3);
        printf("%d+%d=",x,y);
        answer= x + y;
        scanf("%d", &z);//做题人员输入答案
![img](https://img-mid.csdnimg.cn/release/static/image/mid/ask/968849282686139.png "#left")

        if (z == answer)
        {
            score += 10;
            File_in();  //更新计分板
            gotoxy(FrameX+4,FrameY+4);
            printf("                          ");
            gotoxy(FrameX+7,FrameY+4);
            printf("哇!正确,继续加油---"); 
            gotoxy(FrameX+3,FrameY+6);
            printf("                         ");
            correct++;
            gotoxy(FrameX + 2 * Frame_width + 3, FrameY + 5);
            printf("得分:%d  ", score);  //输出当前得分
            


            // 输出小红花
            if (correct % 5 == 0 && !hasGotFlower) { 
                gotoxy(FrameX+4,FrameY+6);
                printf("你真棒!送你一朵小红花!\n"); 
                if (flowerCount == 0) { 
                    int x = 55, y = 12;
                    showOneFlower(x, y);
                    lastFlowerX = x;
                    lastFlowerY = y;
                } else if (flowerCount < 5) { 
                    int x = lastFlowerX;
                    int y = lastFlowerY + 3; 
                    showOneFlower(x, y);
                    lastFlowerX = x;
                    lastFlowerY = y;
                }
                flowerCount++; 
                hasGotFlower = true;
            }
            if (correct == 25) { 
                flowerCount = 0;
            }
            if (correct % 5 != 0) { 
                hasGotFlower = false;
            }
        }
        else
        {
            wrong_answers--;
            if (wrong_answers > 0)
            {
                gotoxy(FrameX + 4, FrameY + 4);
                printf("                       ");
                gotoxy(FrameX + 4, FrameY + 4);
                printf("答案错误,正确答案为:%d", answer);
                gotoxy(FrameX+3,FrameY+6);
                printf("                          ");
            }
            else
            {
                gotoxy(FrameX + 4, FrameY + 8);
                printf("挑战失败,游戏终止");
                Gameover();
                break; // 答错次数达到最大值时跳出循环
            }
        }
        if(correct == 30){
                win();
                

        }
    }
}
Addition();
}

如何清空输入缓冲区

img

img

这是完整的代码,将完整代码提供下,给你查下问题

fflushi(stdin);

不知道你这个问题是否已经解决, 如果还没有解决的话:
  • 给你找了一篇非常好的博客,你可以看看是否有帮助,链接:【C 语言】文件操作 ( C 语言中的文件操作函数 | 磁盘与内存缓冲区 | 缓冲区工作机制 )
  • 除此之外, 这篇博客: C语言清空输入缓冲区中的 C语言编程 - 清空键盘输入缓冲区 部分也许能够解决你的问题, 你可以仔细阅读以下内容或者直接跳转源博客中阅读:

     清空键盘缓冲区很多种方法,如用fflush(stdin); rewind(stdin);等,但是在linux这些都不起作用,还得我今天试了半天都没成功,上网搜了一下发现setbuf(stdin, NULL);就能直接清空键盘缓冲区了。

    以下几个实例:

    Sample one

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12

    #include <stdio.h>

    int main()
    {
        char ch1;
        char ch2;

        ch1 = 

    getchar();
        ch2 = getchar();
        printf("%d  %d", ch1, ch2);
        return 0;
    }

         程序的本意很简单,就是从键盘读入两个字符,然后打印出这两个字符的ASCII码值。可是执行程序后会发现出了问题:当从键盘输入一个字符后,就打印出了结果,根本就没有输入第二个字符程序就结束了。例如用户输入字符’a', 打印结果是97,10。这是为什么呢?

    【分析】:

         scanf()和getchar()函数是从输入流缓冲区中读取值的,而并非从键盘(也就是终端)缓冲区读取。而读取时遇到回车(n)而结束的,这个n会一起读入输入流缓冲区的,所以第一次接受输入时取走字符后会留下字符n,这样第二次的读入函数直接从缓冲区中把n取走了,显然读取成功了,所以不会再从终端读取!其实这里的10恰好是回车符!这就是为什么这个程序只执行了一次输入操作就结束的原因!

    【解决办法】:

         清空缓冲区的残留数据。

         使用 fflush(stdin); 或 rewind(stdin); 均可起到清空键盘缓冲区的作用,这两个函数均包含在stdio.h这个头文件中

    修正后的写法:
    Sample two

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21

    /*
     * 本程序只适用于 Windows 系统,测试平台:
     * Windows XP,Microsoft Visual C++ 6.0 SP6
    */

    #include <stdio.h>

    int main()
    {
        char ch1;
        char ch2;

        scanf("%c", &ch1);
        printf("ch1 = %d", ch1);

        fflush(stdin);   /*清空缓冲区,也可以使用rewind(stdin);*/

        scanf("%c", &ch2);
        printf("ch2 = %d", ch2);
        return 0;
    }

         上面的实例只适用于Windows系统,在Linux环境下上面两种写法都是不起作用的,所以还要换个函数。

    Sample three

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23

    /*
    * 本程序适用于 Windows 和 Linux 系统,
    * 测试环境:
    * Windows XP,Microsoft Visual C++ 6.0 SP6
    * Ubuntu Linux 8.04, NetBeans IDE 6.7
    */

    #include <stdio.h>

    int main()
    {
        char ch1;
        char ch2;

        scanf("%c", &ch1);
        printf("ch1 = %d", ch1);

        setbuf(stdin, NULL); /*清空缓冲区*/

        scanf("%c", &ch2);
        printf("ch2 = %d", ch2);
        return 0;
    }

    ----

     

    source:http://zhidao.baidu.com/question/191469857.html?fr=qrl&cid=866&index=1&fr2=query

    fflush()函数是标准的作法。

    setbuf(stdin,NULL)是GCC下可用的一种方法。

    scanf("%*[^\n]%*c")是用扫描集将缓冲区中的字符全部读取来实现清除缓冲区的动作。

    我最近在ubuntu下写一个程序,涉及到了这方面的问题。用fflush()和setbuf(stdin,NULL)都没有解决掉缓存的问题。 (奇怪的错误,DT地不想调试。)后来,搜到有 scanf("%*[^\n]%*c") 这种方法。非常管用,而且还跨平台。

    scanf("%*[^\n]%*c")解释:

    %*〔^\n〕将逐个读取缓冲区中的'\n'字符之前的其它字符,%后面的*表示将读取的这些字符丢弃,前遇到'\n'字符时便停止读取操作,此时,缓冲区中尚有一个'\n'字符遗留,所以后面的%*c将读取并丢弃这个遗留的换行符,这里的星号和前面的星号作用相同。由于所有从键盘的输入都是以回车结束的,而回车会产生一个'\n'字符,所以将'\n'连同它之前的字符全部读取并丢弃之后,也就相当于清除了输入缓冲区。

  • 以下回答来自chatgpt:

    在c语言中清空输入缓冲区可以使用fflush(stdin)来清空缓冲区。但是这种做法存在很多问题,并不是一个推荐的解决方案,应该避免使用。更好的做法是使用fgets来读取输入,在读取前先清空缓冲区,只读取需要的字符,忽略不需要的字符。具体代码如下:

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    #define MAX_LEN 100
    
    int main() {
        char buffer[MAX_LEN];
        int num;
        fgets(buffer, MAX_LEN, stdin); // 读取一行输入
        num = atoi(buffer); // 转换为数字
    
        while (num <= 0) {
            printf("Please enter a positive number: ");
            fflush(stdout); // 刷新输出缓冲区确保输出能够及时显示
            fgets(buffer, MAX_LEN, stdin); // 读取一行输入
            num = atoi(buffer); // 转换为数字
        }
    
        printf("The number you entered is: %d\n", num);
        return 0;
    }
    

    在这个例子中,我们先使用fgets来读取一行输入,然后使用atoi将输入转换为数字。如果输入不是一个有效的数字,则会被转换为0。我们只需要检查数字是否为正数,如果不是,则提示用户重新输入,直到输入的数字是一个正数为止。由于使用了fgets,我们可以读取任意长度的输入,因此不存在输入缓冲区溢出的问题。而且我们显式地控制了读取的字符数,这意味着我们可以忽略输入缓冲区中的多余字符。

    需要注意的是,我们在每次提示用户重新输入时,都要手动刷新输出缓冲区。这是因为在默认情况下,输出缓冲区中的内容并不会立即输出到屏幕上,而是会等到缓冲区满或者遇到换行符时才会输出。但是由于我们使用了fgets读取输入,输入缓冲区中可能会包含换行符,因此我们需要手动刷新输出缓冲区以确保输出能够及时显示。


如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^

在每个最后不带\n的printf后面加fflush(stdout);
在每个不想受接收缓冲区旧内容影响的scanf前面加rewind(stdin);
另外请检查scanf的返回值。

//请今后要用
char c;
scanf("%c",&c);
//时,都改为
char s[2];
char c;
scanf("%1s",s);
c=s[0];
//自动跳过一个或多个空格或Tab字符或回车换行,读取下一个字符。