过滤掉无效的用户输入

时间:2010-10-06 18:36:22

标签: c++ stl validation

我正在尝试使用以下代码块在小型C ++程序中过滤掉无效的用户输入:

    int selection = -1;
    while (!(selection >= 1 && selection <=4))
    {   
        cin >> selection;

        if (!(selection >= 1 && selection <=4))
        {
            cout << "invalid selection!" << endl;
            cout << "selection: ";
        }
    }

当我输入要在我想要过滤的范围之内或之外的任何数值时,似乎工作正常。但是当我输入无效值(例如大于最大可存储int或字符的值)时会发生奇怪的事情。代码循环并跳过“cin”命令。

我该如何解决这个问题?

由于

5 个答案:

答案 0 :(得分:4)

以下是解决问题的两个建议:

  1. 将错误处理添加到cin
  2. 读为字符串并解析
  3. 常见的解决方案是Read As String And Parse,但我提出了两个供您选择。

    将错误处理添加到cin

    当流提取功能接收到不适合数字的字符时,它会设置fail位。您需要检查流的状态(cin)是否失败。如果要继续,则需要清除错误状态。

    可以使用fail方法检查状态:cin.fail()。要清除状态使用:cin.clear()

    请参阅C++ Online Reference -- istream

    读为字符串并解析

    另一种方法是将输入作为字符串读取,然后解析数据的字符串。 string容器有一些有用的解析方法。

    使用getlinestring读取cin变量。

    同样,您必须编写代码来检查错误并处理它们。

答案 1 :(得分:4)

您需要使用fail()检测不可转换的输入,然后在读取新的输入尝试之前使用cin忽略其余的错误数据并重置clear()错误标记。

int selection = -1;
while (!(selection >= 1 && selection <=4))
{   
    cin >> selection;

    if (cin.fail() || !(selection >= 1 && selection <=4))
    {
        cout << "invalid selection!" << endl;
        cout << "selection: ";

        cin.clear();

        cin.ignore(std::numeric_limits<int>::max(), '\n');
    }
}

答案 2 :(得分:1)

您需要检查cin的条件,如果是任何错误状态,您应该清除错误标记和ignore()

int main()
{
    int selection = -1;
    while (!(selection >= 1 && selection <=4))
    {
        if (cin >> selection)
        {
            if (!(selection >= 1 && selection <=4))
            {
                cout << "invalid selection!" << endl;
                cout << "selection: ";
            }
        }
        else
        {
            cin.clear();
            cin.ignore();
        }
    }

    cout << selection << " selected\n";

    return 0;
}

另一种方法是将所有内容都读为string并让stringstream执行错误检查:

int main()
{
    int selection = -1;
    while (!(selection >= 1 && selection <=4))
    {
        string line;
        getline(cin, line);

        stringstream sstr(line);
        if (sstr >> selection)
        {
            if (!(selection >= 1 && selection <=4))
            {
                cout << "invalid selection!" << endl;
                cout << "selection: ";
            }
        }
        else
        {
            cout << "invalid input!" << endl;
            cout << "selection: ";
        }
    }

    cout << selection << " selected\n";

    return 0;
}

注意:您可能需要在cin.ignore();来电后立即getline() - 取决于您是否正在阅读所有未格式化的输入。

答案 3 :(得分:0)

您应该将cin读入std :: string并从那里开始验证。对于初学者,请检查该值是否为数值。

答案 4 :(得分:-1)

例如,当您输入字母时,它会将cin置于错误状态并保留这些字符。你需要ignore他们(cin.ignore(1024, '\n'))所以它知道继续下一行输入。