菜单输入:检测到无效输入后,所有输入均视为无效

时间:2019-05-09 02:31:29

标签: c++ while-loop getline

我有一个菜单创建系统,其中包含用户可以选择的字符串向量,因此,仅允许菜单选项内的整数作为有效输入。

如果正确输入了数字,则一切正常。如果输入不正确(字符串,浮点数,负数等),则在显示错误消息时不会发生任何事情。

如果尝试输入其他任何内容(有效或无效),则随后的每个输入都将显示错误消息,并且用户将被卡住。

这是我用来验证代码的循环-

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

1 个答案:

答案 0 :(得分:0)

您显示的代码存在一些问题。首先,您不检查std::cin的读取状态。如果出现故障或用户按下文件结束序列,则不会检测到它。

第二,不需要重置std::cin的标志,并且也绝对不需要ignorestd::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来指示任何类型的错误。