我有一个菜单创建系统,其中包含用户可以选择的字符串向量,因此,仅允许菜单选项内的整数作为有效输入。
如果正确输入了数字,则一切正常。如果输入不正确(字符串,浮点数,负数等),则在显示错误消息时不会发生任何事情。
如果尝试输入其他任何内容(有效或无效),则随后的每个输入都将显示错误消息,并且用户将被卡住。
这是我用来验证代码的循环-
bool check = false;
string line;
std::stringstream temp;
int input;
while(!check)
{
getline(cin, line);
temp << line;
temp >> std::noskipws >> input; //this is supposed to reject spaces and floats
if(!temp.fail() && temp.eof() && input > 0 && input <= static_cast<int>(options.size()))
{
check = true; //returns valid value and stops loop
}
else //if all conditions aren't met
{
cin.clear();
cin.ignore();
cout << wrongInput << endl; //prints error
}
}
return input; //correctly returns when valid on first try
在此之前,我只是使用cin >>输入和cin.fail()进行检查,但是这允许通过float并会多次显示错误消息以用于字符串输入。
如果有任何缺少的信息,请告诉我,但是我认为这里的所有内容都是相关的。
编辑:仅仅使用正确的输入来测试我的程序,它似乎开始任意失败。
输入错误的示例:
(menu with numbered options)
intput: "abba" || "3.2" || "4 3" || "-4" || etc.
(no response)
input: "valid number"
(please enter a number from above) - repeats indefinitely
正确输入示例:
(menu with numbered options)
input: "1"
(correctly executes "1" selection, shows menu again)
input: "1"
(again correctly executes "1" selection, shows menu again)
input: "1"
(no response)
input: "1"
(please enter a number from above) - repeats indefinitely
答案 0 :(得分:0)
您显示的代码存在一些问题。首先,您不检查std::cin
的读取状态。如果出现故障或用户按下文件结束序列,则不会检测到它。
第二,不需要重置std::cin
的标志,并且也绝对不需要ignore
从std::cin
来的任何输入。
第三,正如我所提到的,在eof
字符串流中将 not 设置为temp
。还有一种更好的方法来检查错误标志或eof
。
第四,如果您不想要负数,请使用 unsigned 整数类型,并且如果流为负数,流提取将失败。
最后,这更多是个人观点,为什么不留领导空间?真的没有错。
说完所有这些,我将改为执行以下操作:
unsigned input;
std::string line;
while (std::getline(std::cin, line))
{
// Define stream inside the loop, no need to reset it when the loop iterates
std::istringstream istr(line);
// Attempt to extract the value, checking range
if (istr >> input && input > 0 && input <= options.size())
{
// All went okay, the input is valid
break;
}
// If we reach here, there was an error parsing the input
// Or the input was out of bounds
std::cout << wrongInput << '\n';
}
if (!std::cin)
{
// Could not even read from standard input, consider this a fatal error
return EXIT_FAILURE;
}
// Here the variable input contains a value that is larger than zero and smaller or equal to options.size()
如果您需要多次执行此操作,那么我当然建议您将上述代码放入其自己的函数中,以供调用。然后,如果发生故障,您可以返回0
而不是EXIT_FAILURE
来指示任何类型的错误。