循环直到整数输入在所需范围内无法使用非数字字符输入 [英] Loop until integer input is in required range fails to work with non-digit character inputs

查看:19
本文介绍了循环直到整数输入在所需范围内无法使用非数字字符输入的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对应该非常简单的代码有疑问.我想通过错误检查获取 1 到 3 之间的整数.它适用于检查太大或太小的数字,但是当输入字母/数字组合时,它会陷入无限循环.有什么建议吗?

I'm having a problem with what should be incredibly simple code. I want to take in an integer between 1 and 3 with error checking. It works fine for checking for numbers that are too large or too small, but when a alpha/number combination is entered, it gets stuck in an infinite loop. Suggestions?

#include <iostream>
using namespace std;

int main(int argc, char *argv[]){
    int input;

    cout << "
Please enter a number from 1 to 3:" << endl;
    cout << "-> ";
    cin >> input;

    while(input< 1 || input> 3){
        cout << "
---------------------------------------" << endl;
        cout << "
[!] The number you entered was invalid." << endl;
        cout << "
Please re-enter a number from 1 to 3" << endl;
        cout << "-> ";
        cin >> input;
    }

    cout << "You chose " << input << endl;
}

推荐答案

问题是:

cin >> input;

当您尝试读取非数值时,将导致设置错误位.之后,任何使用 operator>> 的尝试都会被忽略.

Will cause the bad bit to be set when you try and read a non numeric value. After that happens any attempt to use the operator>> is silently ignored.

因此,纠正此问题的方法是测试流是否处于良好状态,如果不是,则重置状态标志并再次尝试读取.但请注意,错误的输入(导致问题的)仍在输入上,因此您需要确保也将其丢弃.

So the way to correct for this is to test if the stream is in a good state and if not then reset the state flags and try and read again. But note that the bad input (that caused the problem) is still on the input so you need to make sure you throw it away as well.

if (cin >> input)
{
    // It worked (input is now in a good state)
}
else
{
    // input is in a bad state.
    // So first clear the state.
    cin.clear();

    // Now you must get rid of the bad input.
    // Personally I would just ignore the rest of the line
    cin.ignore(std::numeric_limits<std::streamsize>::max(), '
');

    // now that you have reset the stream you can go back and try and read again.
}

为了防止它被卡住(这是由设置的坏位引起的)读入字符串,然后使用字符串流来解析用户输入.我也更喜欢这种方法(用于用户交互输入),因为它允许更轻松地组合不同的阅读风格(即结合 operator>>std::getline()因为你可以在字符串流上使用这些).

To prevent it getting stuck (which is caused by the bad bit being set) read into a string then use a string stream to parse user input. I also prefer this method (for user interactive input) as it allows for easier combination of different styles of reading (ie combining operator>> and std::getline() as you can use these on the stringstream).

#include <iostream>
#include <sstream>
#include <string>
// using namespace std;
// Try to stop using this.
// For anything other than a toy program it becomes a problem.

int main(int argc, char *argv[])
{
    int          input;

    std::string  line;
    while(std::getline(std::cin, line))   // read a line at a time for parsing.
    {
        std::stringstream linestream(line);
        if (!(linestream >> input))
        {
             // input was not a number
             // Error message and try again
             continue;
        }
        if ((input < 1) || (input > 3))
        {
             // Error out of range
             // Message and try again
             continue;
        }
        char errorTest;
        if (linestream >> errorTest)
        {
             // There was extra stuff on the same line.
             // ie sobody typed 2x<enter>
             // Error Message;
             continue;
        }

        // it worked perfectly.
        // The value is now in input.
        // So break out of the loop. 
        break;
    }
}

这篇关于循环直到整数输入在所需范围内无法使用非数字字符输入的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆