过滤掉无效的用户输入

发布于 2024-09-26 17:32:13 字数 511 浏览 2 评论 0原文

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

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

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

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

我该如何解决这个问题?

谢谢

I'm trying to filter out invalid user inputs in a small C++ program using the following chunk of code:

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

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

It seems to work fine when I enter any numerical value that is either inside or outside the range i want to filter. However strange things happen when I enter invalid values such as values larger than the maximum storable int or characters. The code loops through and skipping the "cin" command.

How do I fix this?

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

别忘他 2024-10-03 17:32:13

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

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');
    }
}

You need to detect unconvertible input using fail() and then ignore the rest of the bad data and reset cin error flags using clear() before reading in a new input attempt.

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');
    }
}
酒解孤独 2024-10-03 17:32:13

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

  1. 将错误处理添加到 cin
  2. 读取为字符串并解析

常见的解决方案是读取为字符串并解析,但我将提供这两种方案供您选择。

cin 添加错误处理

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

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

请参阅 C++ 在线参考 -- istream

读取为字符串并解析

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

使用 getlinecin 读取 string 变量。

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

Here are two suggestions for fixing your issue:

  1. Add Error Handling to cin
  2. Read as String And Parse

The common solution is Read As String And Parse, but I'm presenting both for you to choose.

Add Error Handling to cin

When the stream extraction function receives a character that is not suited for numerics, it sets a fail bit. You need to check the state of the stream (cin) for failure. If you want to continue, you need to clear the error state.

The state can be checked by using the fail method: cin.fail(). To clear the state use: cin.clear().

See C++ Online Reference -- istream

Read As String And Parse

An alternative is read the input as a string, then parse the string for your data. The string container has some useful methods for parsing.

Use getline to read in a string variable from cin.

Again, you will have to write code to check for errors and process them.

您需要检查 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() 调用之后 - 取决于您是否正在读取所有未格式化的输入。

You need to check condition of cin, and if it is any error states, you should clear the error flag and 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;
}

Another way is to read everything as string and let the stringstream do error check:

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;
}

Note: You may need to put a cin.ignore(); right after getline() call - depending on if you are reading all unformatted input or not.

难理解 2024-10-03 17:32:13

您应该将 cin 读入 std::string 并从那里开始验证。首先,检查该值是否为数字。

You should read cin into a std::string and start your validation from there. Check that the value is numeric, for starters.

倾`听者〃 2024-10-03 17:32:13

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

When you enter letters for example it puts cin into a bad state and leaves those characters. You need to ignore them (cin.ignore(1024, '\n')) so it knows to move on to the next line of input.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文