所以我使用do while循环显示菜单,如下所示,我希望用户通过菜单提示,直到他们进行有效选择 - 输入数字1,2,3或4然后,我想使用switch case语句来识别用户选择并执行相关的代码块。但是,当涉及输入验证时,我如何考虑用户输入字母而不是数字?下面的代码成功地继续下一次迭代,以便在用户输入字母时重新启动用户,除非它进入连续循环。
int selection;
do{
cout << "Which option would you like to select? (select 1, 2, or 3)";
cout << "1: Option 1" << endl;
cout << "2: Option 2" << endl;
cout << "3: Option 2" << endl;
if(!(cin >> selection)){
cout << "Please select an integer from 1-4." << endl;
cin.clear()
}
}while(selection != (1) or (2) or (3) or (4));
我尝试使用istringstream插入下面的代码,将用户响应从字符串流式传输到while循环内的int,作为尝试解决问题的替代方法,但无济于事。
string temp;
cin >> temp;
clearInputBuffer();
istringstream is(temp);
is >> selection;
更新代码 - 仍然无限循环(仅当用户输入字母时) 字符;整数行为预期)
int selection;
do{
cout << "Which option would you like to select? (select 1, 2, or 3)";
cout << "1: Option 1" << endl;
cout << "2: Option 2" << endl;
cout << "3: Option 2" << endl;
if(std::cin >> selection){
cout << "Enter the new price: ";
}
else if(!std::cin.eof()){
cout << "Please select an integer from 1-4." << endl;
cin.clear();
}
}while(selection != 1 && selection != 2 && selection != 3 && selection != 4);
答案 0 :(得分:5)
while(selection != (1) or (2) or (3) or (4));
虽然你很可能想要
,但在语法上是有效的while(selection != 1 && selection != 2 && selection != 3 && selection != 4);
您的原始表达相当于
while((selection != 1) || (2) || (3) || (4))
(2)
,(3)
和(4)
被评估为true,这会使您的循环无限,因为anything || true
是true
。
如果有人想知道,是的,C ++允许写and
代替&&
和or
代替||
,而not
代替{{ 1}}等等你必须“禁用语言扩展”才能在MSVC上看到这一点。
[更新]
另一个问题是,在非整数输入的情况下,变量选择保持未初始化。在else子句中,例如,给它一个值-1。
答案 1 :(得分:1)
显而易见的方法是实际检查输入是否成功,如果不是这种情况处理错误,例如,写入错误消息,清除流,忽略字符或行,然后再试一次:
if (std::cin >> selection) {
// do something with the good selection
}
else if (!std::cin.eof()) {
std::cin.clear();
std::cout << "invalid character ('" << char(std::cin.get()) << "') ignored\n";
}
您的代码会检查流并清除它,但它不会提取有问题的字符。当你检查选择是否在范围内时,事情已经很糟糕并且会保持这种状态。
你继续检查范围。当逻辑或运算符评估每个单独的元素时,您的方法不能很好地工作。一种方法是检查输入的值是否是特定rnage的成员,例如,使用
int const valid[] = { 1, 2, 3, 4 };
if (std::end() == std::find(std::begin(valid), std::end(valid), selection)) {
std::cout << "chosen invalid selection (" << selection << ")\n";
}
单独检查每个选择的替代方案对于少量选择可能是可行的,但是当选项范围变得更大时,这是不可行的。不可否认,一旦你有更多的选择,你实际上就把钥匙和操作放在了一起:
std::unordered_map<int, std::function<void()>> actions;
bool done = false;
// set up different operations for the respective actions, e.g.:
actions.insert(std::make_pair(1, [](){ std::cout << "hello, world\n"; }));
actions.insert(std::make_pair(2, [&](){ done = true; std::cout << "goodbye\n"; }))
int selection;
if (std::cin >> selection) {
auto it = actions.find(selection);
if (it != actions.end()) {
(it->second)();
}
else {
std::cout << "unknown action selection " << selection << '\n';
}
}
答案 2 :(得分:0)
试试这个
while(selection != (1) and selection != (2) and selection != (3) and selection != (4));
答案 3 :(得分:0)
selection != (1) or (2) or (3) or (4)
非零整数将评估为true
,因此这相当于:
(selection != (1)) or true or true or true
始终评估为true
。
解决这个问题的方法是逐个比较
while(selection != 1 && selection != 2 && selection != 3 && selection != 4)
答案 4 :(得分:0)
(2),(3,(4)总是如此,这就是为什么你被困在一个无限的角色里。试试:
while(selection != 1 && selection != 2 && selection != 3 and selection != 4);
答案 5 :(得分:0)
更短的版本:
while (selection <= 4 && selection >= 1)
答案 6 :(得分:0)
我得到它的工作,原始帖子中提供的更新缺少一个额外的代码行,我通过筛选有关在while循环中验证输入的其他问题来确定。我认为@DietmarKühl试图在他的建议中说明类似的东西,但是我的编译器不喜欢代码,我不太明白它所以我不知道如何让它工作。我会玩你关于通过Dietmar验证范围的建议,所以感谢您的意见。
还要感谢所有为这个主题做出贡献的人,特别是99%的人这样做而没有听起来居高临下:-)但总有一个。我可以在here找到我找到我遗失的语句的线程,并且添加到代码中的行在下面的代码中用注释标识。再次感谢!
int selection;
do{
cout << "Which option would you like to select? (select 1, 2, or 3)";
cout << "1: Option 1" << endl;
cout << "2: Option 2" << endl;
cout << "3: Option 2" << endl;
if(std::cin >> selection){
cout << "Enter the new price: ";
}
else if(!std::cin.eof()){
cout << "Please select an integer from 1-4." << endl;
cin.clear();
cin.ignore(10000,'\n'); // this line eliminated the infinite loop issue
}
}while(selection != 1 && selection != 2 && selection != 3 && selection != 4);