You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

C++入门疑问:std::cin输入失败后循环陷入死循环的原因及解决办法

问题原因与解决方法

嘿,刚学C++第一天就踩这个输入处理的坑太正常了!我来给你把这个问题讲明白:

为啥会出现无限循环提示?

当你输入字母这类非数字内容时,std::cin >> start会读取失败,这时候会发生两个关键问题:

  1. cin的错误状态位被激活:cin内部有个状态标记,一旦读取失败,它会把自己标记为“错误状态”,之后所有的cin输入操作都会直接跳过,不会再尝试读取用户输入。
  2. 错误输入留在缓冲区:你输入的字母并没有被cin取走,还留在输入缓冲区里,相当于每次循环cin都在反复“看到”这个错误输入,直接判定失败。

你重置start = 0的操作其实没用,因为start只是个普通变量,它的值和cin的状态、输入缓冲区里的内容完全没关系~

解决方法:修复cin状态+清空缓冲区

要解决这个问题,你需要在else分支里做两件事:

  • std::cin.clear()清除cin的错误状态,让它恢复正常工作;
  • std::cin.ignore()把输入缓冲区里的错误内容全部清空,避免下次循环再读到它。

修改后的代码如下(注意要包含<limits>头文件来使用std::numeric_limits):

#include <iostream>
#include <limits> // 要加这个头文件哦

int main() {
    int start = 0, end = 0;
    while(true){
        std::cout<<"Input a starting number: ";
        if(std::cin>>start){
            // 这里可以写输入成功后的逻辑,比如break跳出循环或者继续其他操作
            break;
        }else{
            std::cout<<"You have entered an incorrect starting number. Please enter again."<<std::endl;
            // 第一步:清除cin的错误状态
            std::cin.clear();
            // 第二步:清空输入缓冲区里的所有内容,直到遇到换行符
            std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
            // start重置其实没必要,因为下次输入成功会覆盖它,不过留着也没关系
            start = 0;
        }
    }
    return 0;
}

代码解释:

  • std::cin.clear():把cin的错误状态位重置为正常,这样cin才能继续读取输入;
  • std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n')std::numeric_limits<std::streamsize>::max()表示忽略尽可能多的字符,直到遇到换行符(用户按回车的位置),这样就能把缓冲区里的错误输入全部清掉。

这样修改后,下次循环cin就会重新等待用户输入,不会再无限执行else分支啦~

内容的提问来源于stack exchange,提问作者Khurram Qaseem

火山引擎 最新活动