C++中使用goto处理非法输入时陷入死循环的问题排查
问题分析与修复
你的程序陷入无限循环的核心原因是:当输入非法值后,cin的错误标志位被置位,导致后续所有读取操作直接失败,同时输入缓冲区里的非法数据没有被清除,每次循环都会重复读取这些无效数据,从而不断触发错误提示。另外,std::isnan(human_years)完全无效——因为human_years是int类型,不可能存储NaN值。
修复步骤
- 移除无效的
std::isnan判断 - 输入失败时,重置
cin的错误状态 - 清空输入缓冲区中的非法残留数据
- (可选)替换
goto为更符合C++风格的循环结构
修复后的代码(保留goto版本)
#include <iostream> #include <limits> // 用于numeric_limits using namespace std; int main() { int human_years, dog_per_human_age, dog_years; starthere: cout << "How many years ago did you buy your dog?" << endl; cin >> human_years; if (cin.fail()) { cout << "Non numerical value inserted! Please try again.\n"; cin.clear(); // 重置cin的错误状态 // 清空缓冲区直到换行符,清除所有非法残留数据 cin.ignore(numeric_limits<streamsize>::max(), '\n'); goto starthere; } else { dog_per_human_age = 5; dog_years = human_years * dog_per_human_age; cout << "Your Dog is " << dog_years << " years old."; return 0; } }
更规范的循环版本(推荐)
用while循环替代goto,代码结构更清晰:
#include <iostream> #include <limits> using namespace std; int main() { int human_years, dog_per_human_age, dog_years; while (true) { cout << "How many years ago did you buy your dog?" << endl; cin >> human_years; if (!cin.fail()) { dog_per_human_age = 5; dog_years = human_years * dog_per_human_age; cout << "Your Dog is " << dog_years << " years old."; break; } cout << "Non numerical value inserted! Please try again.\n"; cin.clear(); cin.ignore(numeric_limits<streamsize>::max(), '\n'); } return 0; }
关键说明
cin.clear():重置cin的错误标志位,让它恢复到可读取状态cin.ignore(numeric_limits<streamsize>::max(), '\n'):从输入缓冲区中读取并丢弃所有字符,直到遇到换行符,彻底清除上次输入的非法数据- 移除冗余头文件:
bits/stdc++.h已经包含了几乎所有标准库头文件,单独的cmath可以省略;如果追求代码简洁,也可以只保留bits/stdc++.h,但推荐只包含必要头文件。
内容的提问来源于stack exchange,提问作者David Orizu
相关产品推荐
相关产品推荐

