输入验证以滤除字符,字符串和整数范围

时间:2018-10-13 03:33:49

标签: c++

我已经在Internet上的多个地方查看过,但是找不到我想要的内容。基本上,我试图理解数据验证并过滤掉除数字1或2之外的所有用户输入。我发现了用于验证整数的信息。找到了有关过滤字符和字符串的内容。但是,当我尝试将它们放在一起时,它不起作用。基本上,如果用户输入的内容不是1或2,则不会结束循环,要求输入正确的内容。

我在下面的代码的注释中包含了更多详细信息。

感谢您的帮助!

#include <iostream>
#include <string>

int main()
{
    std::cout << "Please enter 1 or 2.  No other numbers or characters." 
        << std::endl;

    std::string numberString;

    //Used a string so if the user enters a char it gets converted to an 
    //integer value of 0.
    getline(std::cin, numberString);
    int numberInteger = atoi(numberString.c_str());

    //If the user enters the wrong number, char, or string, 
    //the program goes to this area of code.  
    //But if a subsequent correct entry is made, the loop does not end.
    if (numberInteger < 1 || numberInteger > 2)
    {
        do
        {
            //Tried using these two lines of code to clear the input buffer, 
            //but it doesn't seem to work either:
            //std::cin.clear();
            //std::cin.ignore(std::numeric_limits <std::streamsize>::max(), '\n');

            std::cout << "Invalid input.  Please enter 1 or 2.  No other numbers or characters." 
            << std::endl;
            getline(std::cin, numberString);
            int numberInteger = atoi(numberString.c_str());
        } while (numberInteger < 1 || numberInteger > 2);
    }

    else
    {
        std::cout << "You entered either 1 or 2.  Great job! " 
        << std::endl;
    }

    return 0;
}

1 个答案:

答案 0 :(得分:1)

#include <cctype>
#include <limits>
#include <iostream>

std::istream& eat_whitespace(std::istream& is)
{
    int ch;
    while ((ch = is.peek()) != EOF && ch != '\n' &&
           std::isspace(static_cast<char unsigned>(ch))) // 0)
        is.get();  // As long as the next character
                   // is a space, get and discard it.
    return is;
}

int main()
{
    int choice;
    while (std::cout << "Please enter 1 or 2. No other numbers or characters: ",
           !(std::cin >> std::skipws >> choice >> eat_whitespace) ||  // 1)
           std::cin.peek() != '\n' ||  // 2)
           choice < 1 || 2 < choice) {  // 3)
        std::cerr << "I said 1 or 2 ... nothing else ... grrr!\n\n";
        std::cin.clear();  // 4)
        std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');  // 5)
    }

    std::cout << "Input was " << choice << '\n';
}

0)不要输入isspace()负值。
1)提取int失败。在int前后留空格。
2)如果流中的下一个字符不是换行符,则剩下的垃圾eat_whitespace()没被吞下->抱怨。
3) choice不在范围内。
4)清除标志,以确保输入功能可以再次使用。
5)最多忽略streamsize个字符,直到下一个换行符为止。