c++ - 输入验证以过滤掉字符、字符串和一系列整数

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

最佳答案

#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) 选择不在范围内。
4) 清除标志以确保输入功能将再次工作。
5) 忽略最多 streamsize 个字符,直到下一个换行符。

关于c++ - 输入验证以过滤掉字符、字符串和一系列整数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52789275/

相关文章:

c++ - 将 vector 的元素转换为用户定义的类型

c++ - 如何让程序在启动时运行?

c++ - throw/catch on stack unwind 是否安全?

c++ - boost asio 读取动态大小消息

c++ - 捕获预定义的 int 异常

c++ - 如何在不将输入和输出定向到标准输入的情况下使用 popen 在 C++ 中打开进程?

C++ c_str() 奇怪的行为

c++ - 为随机生成的字符串 C/C++ 打印字符,不在随机列表中的字符也被打印

c++ - C++中从float到double的转换

c++ - std::vector 转换运算符的 C2664