C ++中的整数输入验证

时间:2014-06-29 20:34:33

标签: c++

我对C ++中的输入验证有疑问。这是我遇到问题的代码:

#include <iostream>
using namespace std;

int main()
{
    int in;

    while(true)
    {
        if(cin >> in)
        {
            if(in < 0 || in > 2)
            {
                cout << "Invalid input.  Number needs to be 0, 1, or 2.";
                cin.clear();
                while(cin.get() != '\n');
                cin.ignore();
            }
            else
            {
                cout << "Output: " << in;
                break;
            }
        }
        else
        {
            cout << "Invalid input. Please enter a number.";
            cin.clear();
            while(cin.get() != '\n');
            cin.ignore();
        }
    }
}             

此代码正常工作,除非使用表格&#39; 12hfhd&#39;的第二个输入连续创建两个无效条目。然后它接受这个作为输入,我无法弄清楚原因。我搜索了SO并找到了一些关于输入验证的问题,但似乎无法找到任何有关其代码接受某些输入的信息。

3 个答案:

答案 0 :(得分:6)

主要问题是,当使用int运算符从std::cin请求>>时,将转换输入开头的一系列数字字符。例子:

  • 2将转换为2
  • 75$将转换为75
  • 12asdfgh将转换为12
  • hello,world会转换为0,因为第一个字母已经不是数字

最好的办法是使用一些char操作:

int getNumber() {
  char input;
  std::cin >> input;
  if(input > '2' || input < '0') { // yes, chars act like ASCII numbers
    // handle this problem
    return -1; //error
  } else {
    return int(input - '0'); // input's code - '0''s code = number
  }
}

答案 1 :(得分:0)

在处理用户输入时我会使用以下方法:

string l;
if(!getline(cin, l))
    /* handle error that no input could be read at all */
try
{
    int const res = boost::lexical_cast<int>(l);
    /* numerically validate input here */
    return res;
}
catch(exception const&)
{
    /* handle parsing error here */
}

单词中,读取一行,然后使用Boost的lexical_cast()函数模板进行解析和验证。请注意,如果有人从文件中读取输入(例如,通过shell重定向),则会发生getline()失败的第一个错误,但这也可以通过某些按键来实现,具体取决于shell。此状态无法恢复,因此提示输入不同的答案将导致无限循环。

答案 2 :(得分:0)

如果您查看&gt;&gt;的文档提取运算符,例如:

http://www.cplusplus.com/reference/istream/istream/operator%3E%3E/

你会注意到以下引用:

  

(1)算术类型       从流中按顺序提取和解析字符,将它们解释为正确类型值的表示,   它存储为val的值。

这实际上意味着程序将尝试将您传递的所有数据视为以rvalue指定的格式进行格式化,在您的情况下为int。更简单:在您的情况下,它会尝试对您传入流中的内容进行整理,并使数据变为“整数”。