如何在函数中创建一个循环来获取一个既是数字又在特定范围内的 cin 以返回值?

How do I create a loop in a function to get a cin that is both a number and in a certain range, to return the value?

提问人:Steve lel 提问时间:5/4/2023 更新时间:5/4/2023 访问量:36

问:

嗨,我需要在一个需要显示菜单的类中创建一个 int 成员函数,然后提示用户输入一个既是数字又介于 1-5 之间的 cin 输入。它需要循环 cin,直到给出正确的值,根据问题显示不同的错误消息:然后它需要能够返回该值。

这是我的 c++ 代码

int ClassName::menu() {
        cout << "Menu title" << endl;
        cout << "1- option1" << endl;
        cout << "2- op 2" << endl;
        cout << "3- op 3" << endl;
        cout << "4- op 4" << endl;
        cout << "5- op 5" << endl;
        cout << "0- exit program" << endl;
        cout << "> ";
        int flag = 1;
        int value;
        string input;
        while (flag == 1) {
            getline(cin, input);
            value = stoi(input);
            if (input[0] < '0' || input[0] > '5') {
                cout << "Invalid Integer, try again: ";
                input.clear();
            }
            else if (value < 0 || value > 5) {
                    cout << "[0<=value<=5], retry: ";
                    input.clear();
            }
            else {
                flag = 0;
            }
        }
        return value;
    }
C++ 成员函数

评论

0赞 paddy 5/4/2023
怎么了?据我所知,您的程序只会在非整数输入时崩溃,除非您正在处理此代码之外的异常。请注意,如果转换失败,将抛出。因此,您应该将其包装在 try-catch 中,并忘记您正在检查字符的第一个 if 语句。std::stoiinput
0赞 Steve lel 5/4/2023
我不能使用 try,我不希望我的程序崩溃。那我该怎么办?我必须搬家吗?
0赞 paddy 5/4/2023
为什么不能使用?它一直是 C++ 的功能。无论如何,您可以改用 std::strtol 并执行其他验证,例如确保未解析字符串的其余部分为空或空格,并且返回值没有文档中的范围错误。或者,您可以在调用之前手动完成所有整数验证,前提是您捕获可能导致它抛出的所有内容。trystd::stoi
1赞 Remy Lebeau 5/4/2023
@Stevelel“那我该怎么办?我必须搬家吗?- 不,你应该首先停止使用,对于你试图完成的任务来说,它是错误的工具。stoi

答:

0赞 Remy Lebeau 5/4/2023 #1

stoi()如果转换失败,则引发异常,但您没有捕获异常。

成功将输入字符串转换为整数后,无需查看输入的单个字符,特别是因为您甚至没有查看整个输入。

但实际上,为什么要首先将输入读取到字符串中,然后将其转换为整数?您应该改用直接将输入读入整数。operator>>

此外,您没有正确使用。它不会从输入缓冲区中删除数据。它会重置流的错误状态,但您在流未处于错误状态的位置调用它。cin.clear()

请尝试以下操作:

int ClassName::menu() {
    cout << "Menu title" << endl;
    cout << "1- option1" << endl;
    cout << "2- op 2" << endl;
    cout << "3- op 3" << endl;
    cout << "4- op 4" << endl;
    cout << "5- op 5" << endl;
    cout << "0- exit program" << endl;
    cout << "> ";

    int value;
    do {
        if (cin >> value) {
            if (value >= 0 && value <= 5) {
                break;
            }
            cout << "Invalid choice, retry: "; 
        }
        else {
            cin.clear();
            cin.ignore(numeric_limits<streamsize>::max(), '\n');
            cout << "Invalid input, retry: ";
        }
    }
    while (true);

    return value;
}