C++中switch语句如何拒绝同时包含合法与非法字符的混合输入?
问题原因
你遇到的异常和switch语句本身没有任何关系,问题出在输入读取逻辑上:cin.get()每次只会从输入缓冲区读取单个字符,用户输入的所有内容(包括回车)都会按顺序存在缓冲区里排队等待读取。比如输入-1后敲回车,缓冲区里会依次存入'-'、'1'、'\n'三个字符:
- 第一次循环读取到
'-',匹配default分支,输出错误提示,x--让循环继续执行 - 第二次循环读取到
'1',匹配case '1'分支,输出选中结果,循环结束 - 剩余的
'\n'还会留在缓冲区中,就出现了输入一次却触发两次逻辑的问题。
你之前想到的for循环配合x--实现重复输入的逻辑本身是可用的,只要修正输入读取逻辑就能解决问题。
解决方案
这里提供两种常用的修复方案:
方案1:每次处理后清空输入缓冲区
每次读完当前字符后,直接清空输入缓冲区中剩余的所有内容,避免残留字符被下一次循环读取。你只需要做两处修改:
- 在文件头部引入
<limits>头文件 - 在
switch语句结束后、for循环内部添加清空缓冲区的代码:
for (int x = 0; x < 1; x++) { switch (cin.get()) { // 原有case逻辑保持不变 ... } // 新增:清空缓冲区到换行符为止 cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); }
方案2:直接读取整数判断(更符合题目设计)
题目要求用户输入1-5的数字,直接读取整数类型更合理,还能自动跳过空格、回车等空白字符,同时支持处理非数字输入的异常情况,健壮性更强,完整修改后的逻辑如下:
#include <iostream> #include <string> #include <limits> using std::cout; using std::cin; using std::endl; using std::string; int main() { string drink1 = "Water", drink2 = "Coke", drink3 = "Pepsi", drink4 = "Orange Juice", drink5 = "Powerade"; string choose_text = "\n\nChoose your preferred drink: ", chosen_text = "\nYou have chosen: "; cout << "1.) " << drink1.append(17 - drink1.length(), ' ') << "2.) " << drink2.append(17 - drink2.length(), ' ') << "3.) " << drink3.append(17 - drink3.length(), ' ') << "4.) " << drink4.append(17 - drink4.length(), ' ') << "5.) " << drink5.append(17 - drink5.length(), ' ') << choose_text; int choice; while (true) { cin >> choice; // 处理输入为非数字的异常 if (cin.fail()) { cin.clear(); // 重置输入流错误状态 cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // 清空缓冲区 cout << "\nError. Choice was not valid.\nPlease enter an option 1 - 5." << choose_text; continue; } // 判断数字范围是否合法 if (choice >= 1 && choice <=5) { cout << chosen_text; switch(choice) { case 1: cout << drink1 << endl; break; case 2: cout << drink2 << endl; break; case 3: cout << drink3 << endl; break; case 4: cout << drink4 << endl; break; case 5: cout << drink5 << endl; break; } break; } else { cout << "\nError. Choice was not valid.\nPlease enter an option 1 - 5." << choose_text; cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); } } return 0; }
内容的提问来源于stack exchange,提问作者Rodrigo Ponce
相关产品推荐
相关产品推荐

