循环直到整数输入在所需范围内无法处理非数字字符输入
Loop until integer input is in required range fails to work with non-digit character inputs
我对应该非常简单的代码有问题。 我想通过错误检查接收一个介于 1 和 3 之间的整数。 它适用于检查太大或太小的数字,但是当输入字母/数字组合时,它会卡在无限循环中。 建议?
#include <iostream>
using namespace std;
int main(int argc, char *argv[]){
int input;
cout << "nPlease enter a number from 1 to 3:" << endl;
cout << "-> ";
cin >> input;
while(input< 1 || input> 3){
cout << "n---------------------------------------" << endl;
cout << "n[!] The number you entered was invalid." << endl;
cout << "nPlease re-enter a number from 1 to 3" << endl;
cout << "-> ";
cin >> input;
}
cout << "You chose " << input << endl;
}
问题是:
cin >> input;
将导致在尝试读取非数值时设置坏位。发生这种情况后,任何使用该operator>>
的尝试都将被静默忽略。
因此,纠正此问题的方法是测试流是否处于良好状态,如果不是,则重置状态标志并尝试再次读取。但请注意,错误的输入(导致问题)仍在输入上,因此您需要确保也将其丢弃。
if (cin >> input)
{
// It worked (input is now in a good state)
}
else
{
// input is in a bad state.
// So first clear the state.
cin.clear();
// Now you must get rid of the bad input.
// Personally I would just ignore the rest of the line
cin.ignore(std::numeric_limits<std::streamsize>::max(), 'n');
// now that you have reset the stream you can go back and try and read again.
}
为了防止它卡住(这是由设置的坏位引起的),读入字符串,然后使用字符串流来解析用户输入。我也更喜欢这种方法(用于用户交互式输入),因为它允许更容易地组合不同的阅读风格(即结合operator>>
和std::getline()
,因为您可以在字符串流上使用它们)。
#include <iostream>
#include <sstream>
#include <string>
// using namespace std;
// Try to stop using this.
// For anything other than a toy program it becomes a problem.
int main(int argc, char *argv[])
{
int input;
std::string line;
while(std::getline(std::cin, line)) // read a line at a time for parsing.
{
std::stringstream linestream(line);
if (!(linestream >> input))
{
// input was not a number
// Error message and try again
continue;
}
if ((input < 1) || (input > 3))
{
// Error out of range
// Message and try again
continue;
}
char errorTest;
if (linestream >> errorTest)
{
// There was extra stuff on the same line.
// ie sobody typed 2x<enter>
// Error Message;
continue;
}
// it worked perfectly.
// The value is now in input.
// So break out of the loop.
break;
}
}
#include <iostream>
#include <string>
using namespace std;
int validatedInput(int min = 1, int max = 3)
{
while(true)
{
cout << "Enter a number: ";
string s;
getline(cin,s);
char *endp = 0;
int ret = strtol(s.c_str(),&endp,10);
if(endp!=s.c_str() && !*endp && ret >= min && ret <= max)
return ret;
cout << "Invalid input. Allowed range: " << min << "-" << max <<endl;
}
}
int main(int argc, char *argv[])
{
int val = validatedInput();
cout << "You entered " << val <<endl;
return 0;
}
这些答案中的大多数都包含不必要的复杂性。
输入验证是使用 do-while 的最佳时机
do{
cout << "nPlease enter a number from 1 to 3:" << endl;
cout << "-> ";
if(!cin){
cout << "Invalid input"
cin.clear()
cin.ignore(numeric_limits<streamsize>::max(), 'n');
}
}while(!(cin >> input))
使用
numeric_limits<streamsize>::max()
完全清除cin
失败后的缓冲区。使用
cin.clear()
重置cin
上的失败标志,以便!cin
不会 总是评估错误。
cin.fail()
很好。然而,有些人会认为!cin
更自然。
从我之前的帖子 https://stackoverflow.com/a/43421325/5890809
您将输入声明为 int,但是当您编写字母数字字符进行输入时,它将尝试将其隐式转换为整数。但是您的错误检查并不能说明这一点。
您的问题可以通过更改 while 循环轻松解决。 而不是检查这个,你检查一下怎么样
while(input!=1 || input!=2 || input!=3)
相关文章:
- 如何忽略第一个字符输入后的所有内容
- 使用单个变量对字符输入进行计数
- 全新C++.处理用户输入
- 我如何处理有关输入的字符串大小超过字符数组设置大小的错误?
- 有没有办法在使用 GLFW 按下按键后只处理一个输入事件?
- 确定用户字符输入 C++ 的结束
- 将单个字符串/字符输入串行监视器
- 如何将字符输入限制为仅获取一个字符串"cin"
- C++:使用 fgets() 读取字符输入时出错
- 如何拒绝 cin 中的字符输入并定义最小和最大整数值
- SCANF 如何处理标准输入与流水线输入
- 我在处理字符时遇到麻烦
- C++ 字符输入仅输出第一个字母
- 处理字符到QString转换中的ASCII字符
- 限制 2D 数组中的字符输入
- 可以处理大输入(2GB)的JSON解析器
- 循环直到整数输入在所需范围内无法处理非数字字符输入
- C 如何处理字符和
- C++常量字符*输入
- 以字符串作为输入,但在c++中单独处理字符