使用cin.getline()时输入'n'需按两次回车的问题排查
嘿,我找到你这个“输入'n'要按两次回车”问题的根源了!
问题原因
这是个很常见的输入缓冲区残留问题:如果这段代码之前你用了cin >>之类的输入方式,用户输入后按下的回车(\n)会留在输入缓冲区里。当你的getline第一次执行时,它会直接读取这个空的换行字符串,触发checkinput的异常(因为空串不是y/n),导致test被设为true,循环重新执行。这时候你第二次输入'n'并回车,才会被getline正确读取,所以看起来需要按两次回车。至于输入'y'时你觉得正常,大概率是没注意到第一次其实也触发了一次异常提示,或者后续流程掩盖了这个小问题。
修复方案
1. 清除输入缓冲区的残留字符
在进入do-while循环前,添加一行代码清除缓冲区里的残留换行符。记得要包含<limits>头文件:
#include <limits> // ... cin.ignore(numeric_limits<streamsize>::max(), '\n');
这行代码会把缓冲区里直到换行符的所有字符都忽略掉,确保第一个getline能直接读取你输入的内容。
2. 修复checkinput函数的小问题
你原来的checkinput函数漏掉了返回类型声明,而且里面的cin.fail()判断其实没用(getline读取失败时,choice是空串,前面的判断已经会抛出异常了)。修改后的函数应该是:
string checkinput(string c) { if (c != "Y" && c != "y" && c != "N" && c != "n") { throw 1; } return c; }
修改后的完整代码示例
#include <iostream> #include <string> #include <limits> using namespace std; string checkinput(string c) { if (c != "Y" && c != "y" && c != "N" && c != "n") { throw 1; } return c; } int main() { bool test = true; string choice; // 清除缓冲区残留的换行符 cin.ignore(numeric_limits<streamsize>::max(), '\n'); do { try { if (test) cout << " Re-enter: "; test = false; getline(cin, choice); checkinput(choice); } catch (int flag) { if (flag == 1){ cout << "Error: Input must be y or n.\n"; test = true; } } } while (test); cout << "You entered: " << choice << endl; return 0; }
这样修改后,不管输入'y'还是'n',只需要按一次回车就能正常执行啦!
内容的提问来源于stack exchange,提问作者Tom Smith
相关产品推荐
相关产品推荐

