ITPub博客

首页 > > > C语言-scanf缓存造成无限死循环

C语言-scanf缓存造成无限死循环

作者:dapan 时间:2018-12-07 16:22:04 0 删除 编辑

上一篇关于scanf的文章链接如下

嵌入式Linux:C语言 scanf 小结​zhuanlan.zhihu.com图标


今天,有个同事发了下面的代码给我

#include<stdio.h>
int main()
{
    int score;
    loop:
    scanf("%d",&score);
    if(score < 0 || score > 100){
        printf("please input again:\n");
    goto loop;
    }

    if(score>=80&&score<=100)
        printf("A\n");
    else if(score>=60&&score<=79)
        printf("B\n");
    else if(score>=40&&score<=59)
        printf("C\n");
    else
        printf("D\n");
    return 0;
}

作为一个老司机,我相信这个代码里面肯定是有毒的,如果没毒,这个锤子也不会发给我这个坑,他让我运行后输入字符 ‘d’.

要想填好坑,首先你要先入坑,所以,我还是照着这厮的话运行了一次,运行结果如下图

实际运行的代码


然后我经过各种努力,各种百度,各种google,

终于得出下面的结论

scanf("%d",&score);

原因:这个代码是从输入流里面获取整型数据,如果你输入一个字符型的,scanf不拿这个字符的数据出来,这个数据就一直在缓存里,最后就导致了死循环。

如果这个缓冲区在栈内分配的,我们是不用管的,之前有个文章说过,栈主要是有操作系统管理的,但是如果这个缓冲区在堆内分配,我们就需要手动清除,就像malloc 需要和free配合使用一样。


解决办法:

  • fflush(stdin)-这个只能保证在VC上可以生效,在其他编译器上不保证可以起作用。
  • setbuff(stdin,NULL)-这个是操作指针,把输入流从默认缓冲区改到一个NULL的地方,避免默认的缓冲区有缓存值。
  • while((c = getchar()) != '\n' && c != EOF);-这个是缓冲区有值,我用getchar()把这个值读走,这也是清缓冲区的一个方法。


最终代码

#include<stdio.h>

void safe_flush()
{
    char c;
    while((c = getchar()) != '\n' && c != EOF);
}

int main()
{
    int score;
    loop:
    scanf("%d",&score);
    if(score < 0 || score > 100){
        safe_flush();
        printf("please input again:\n");
    goto loop;
    }

    if(score>=80&&score<=100)
        printf("A\n");
    else if(score>=60&&score<=79)
        printf("B\n");
    else if(score>=40&&score<=59)
        printf("C\n");
    else
        printf("D\n");
    return 0;
}

运行如下:

修改后的运行结果


欢迎关注微信公众号-嵌入式Linux

觉得不错,请帮忙转发,点赞,您的每一次支持,我都将铭记于心

原文作者:;如有侵权,请联系管理员删除。

请登录后发表评论 登录
全部评论

注册时间:2020-08-07

  • 博文量
    4504
  • 访问量
    87278