C++ Code::Blocks Linux控制台菜单非法输入校验问题求助
问题根因
当cin接收的输入和变量类型不匹配时(比如给int类型的option传入字母),会触发fail错误状态,后续所有cin操作都会直接跳过不会等待用户输入,同时非法输入会一直残留在输入缓冲区中,每次循环都会读取到相同的错误内容,最终进入死循环。
最简修复方案
只需要3步改动即可解决问题:
- 新增引入
<limits>头文件,用于获取输入缓冲区的最大长度 - 每次执行
cin >> 变量操作后,先检查输入是否出错,如果出错就先重置cin的错误状态,再清空缓冲区所有残留内容 - 即使输入合法,也要清空缓冲区残留的换行符,避免后续的等待输入操作直接读到换行直接返回
修改后的完整代码如下:
#include <iostream> // 新增头文件,用于清空输入缓冲区 #include <limits> using namespace std; void showMenu() { cout << "---------------MENU --------------" << endl; cout << "1- Check balance :" << endl; cout << "2- Check deposit :" << endl; cout << "3- Withdraw:" << endl; cout << "4- Exit" << endl; cout << "--------------------------------" << endl; } int main() { int option; double balance = 500; do { showMenu(); cout << "Option: "; cin >> option; // 新增输入校验逻辑 if (cin.fail()) { // 重置cin的错误状态 cin.clear(); // 清空缓冲区所有内容直到遇到换行符 cin.ignore(numeric_limits<streamsize>::max(), '\n'); // 将option设为非法值,触发default分支提示 option = -1; } else { // 输入合法的情况下也要清空残留的换行符 cin.ignore(numeric_limits<streamsize>::max(), '\n'); } cout << "\033[2J\033[1;1H"; switch(option) { case 1: cout << "Balance is: " << balance << " $" << endl; break; case 2: cout << "Deposit amount: " << endl; double depositAmount; cin >> depositAmount; // 存款输入校验,避免非法值崩溃 if (cin.fail()) { cin.clear(); cin.ignore(numeric_limits<streamsize>::max(), '\n'); cout << "Invalid deposit amount" << endl; break; } cin.ignore(numeric_limits<streamsize>::max(), '\n'); balance += depositAmount; break; case 3: cout << "Withdraw amount: " << endl; double withdrawAmount; cin >> withdrawAmount; // 取款输入校验 if (cin.fail()) { cin.clear(); cin.ignore(numeric_limits<streamsize>::max(), '\n'); cout << "Invalid withdraw amount" << endl; break; } cin.ignore(numeric_limits<streamsize>::max(), '\n'); if (withdrawAmount <= balance) { balance -= withdrawAmount; } else { cout << "Not enough money" << endl; } break; default: cout << "Your choice is invalid "; cout << '\n' << "Press the Enter key to continue."; // 缓冲区已清空,可正常等待用户按回车 cin.get(); } } while(option != 4); return 0; }
补充说明
上述方案完全适配Linux环境,不需要依赖system("pause")即可实现暂停效果。如果不需要对存款、取款的输入做校验,也可以只保留菜单选项处的校验逻辑,即可解决最核心的无限循环问题。
内容的提问来源于stack exchange,提问作者Joc380
相关产品推荐
相关产品推荐

