dev c++中关于scanf的问题!

有没有人可以帮忙解答一下:
写的是线性表输出n遍的代码,不知道为什么,运行程序之后显示scanf上一行那个printf能正常显示,但是你输个3之后按回车,光标就停在了下一行上了,这是什么问题呢导致的呢?

img

img

++k修改为++i
死循环了。

不知道你这个问题是否已经解决, 如果还没有解决的话:
  • 帮你找了个相似的问题, 你可以看下: https://ask.csdn.net/questions/7626403
  • 这篇博客你也可以参考下:在C语言中为什么scanf输入语句,要在变量名前加&呢?
  • 除此之外, 这篇博客: C语言判断scanf输入的是否为整型,以及由此造成死循环的解决办法中的 判断scanf输入的是否为整型 部分也许能够解决你的问题, 你可以仔细阅读以下内容或者直接跳转源博客中阅读:

    # 需求
    很多时候我们需要用scanf输入数据,但人为输入的数据可能不符合指定的类型,自然地我们想到了判断输入类型是否正确。

    # 实现
    那该怎么实现呢?这里我们可以利用scanf的返回值:
    scanf返回值:返回成功读入的数据项数

    既然这样,那只需要加一个循环,每次检测录入的数据项数是否为全部数据的个数,不是则说明有内容没有录取到(即出现非法字符),此时可以输出提示要求重新输入。

    自然地我们写出以下代码:

    //以检查输入的是否一个整型为例(VS2019)
    int n;
    while (scanf_s("%d", &n) == 0)
    {
    	printf("输入了非法字符!\n");
    }
    

    !!但是,问题出现了
    输入非法字符后,结果是这样的:
    啊这,发生了甚么?!

    可以看到,while变成死循环了,并没有给我们再次输入的机会QAQ,到底发生了甚么?!

    # 分析
    这时候就需要看看scanf的运作原理了
    当要求的类型与输入的类型不符合时,scanf会选择直接跳过不接收该输入,注意只是不接收,也就是说缓存区中输入的东西既没被接收也没有被清除,就这么留在那里。

    那问题就来了,当下一次用户要输入时,scanf看到缓存区有东西,就直接去读取了,结果又读到与指定类型不符合的,又跳过了,由此触发了无限循环(傻fufu的)

    # 解决方案
    完成了分析,接下来就好处理了,只需要把缓存区的东西清掉不要让scanf傻傻的又去读取就好啦!

    相关代码段:while (getchar() != '\n');
    这一句可以简单地解决清楚缓存区的功能
    原理是每次都向缓存区读取数据,如果没到尾就继续读取,直到把所有东西读完,再跳出(注意while执行的是空语句)

    到这里,问题就都解决了 – 需求 OK,bug KO

    # 完整代码

    //以检查输入的是否一个整型为例(VS2019)
    int n;
    while (scanf_s("%d", &n) == 0)
    {
    	printf("输入了非法字符,请重新输入:");
    	while (getchar() != '\n');
    }
    

    *注:这里的getchar已经不用自己输入了,原因和scanf的死循环一样,缓冲区已经有东西了,getchar会直接读取而不会让我们输入

    运行结果:
    在这里插入图片描述

    可以看到问题已经完美解决了~


    2021-3-29 方案完善

    在后续的使用中,出现了一些问题,如下:
    在这里插入图片描述
    可以看到:
    当输入的数据以数字开头,而带有字符时
    该解决方案会截取到数字部分,视为合法数据,而后面的字符则留在了缓冲区

    这将直接导致下一次的输入被跳过直接取出缓冲区的字符,显然不是我们希望的,所以做了如下改进:

    int n;
    while (scanf_s("%d", &n) == 0 || getchar() != '\n')
    {
    	printf("输入了非法字符,请重新输入:");
    	while (getchar() != '\n');  // 清除缓存区
    }
    

    解释:

    • 如果为 0 则说明第一个位置出现了字符
    • 不为 0 说明前面是整型,此时再取出后面一个字符
    • 如果为 \n 则数据没问题,要是还有东西则又是非法字符

    这样就可以保证输入的全部为所需的整型

    效果如下:
    在这里插入图片描述

    好的,完结收工~
    如果还有后续问题欢迎指正!


    第3篇完成,打卡!!
    冰冻三尺非一日之寒(寒冰小澈)

  • 您还可以看一下 李南江老师的零基础学会C语言课程中的 scanf函数注意点(掌握)小节, 巩固相关知识点

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