如何进行良好的验证来检查输入是数字

How to have a good validation to check input is numeric

本文关键字:检查 输入 数字 验证 何进行      更新时间:2023-10-16

我在SO中看到过几篇要求验证输入是否为数字的帖子。然而,他们提出的解决方案似乎存在缺陷。

考虑以下数字输入示例:

for (int x=0; x<10; x++)
{
    cout << x+1 <<  ") Input a number: ";
    cin >> num;
    while (cin.fail())
    {
        cin.clear();
        cin.ignore(200, 'n');           
        cout << x+1 << ") Input a number: ";
        cin >> num; 
    }
    cout << "Your Number: " << num << endl;
}

示例程序输入/输出:

1) Input a number: aaa a
1) Input a number: 50
Your Number: 50
2) Input a number: 3a b c 
Your Number: 3
3) Input a number: 3) Input a number:   <= How to prevent these duplicated prompts?

我上面使用的代码是从过去SO职位中投票率最高的一些解决方案中获得的。但是,如果我们给出一个字母数字输入,在提示下一个输入时会导致重复提示。

注意:建议的解决方案最好避免使用C++11中的函数。

我的问题是:我们如何克服这个问题?

我已经找到了一种明确防止重复提示的可能方法。

for (int x=0; x<10; x++)
{
    cout << x+1 <<  ") Input a number: ";
    cin >> num;
    while (cin.fail())
    {
        cin.clear();
        cin.ignore(200, 'n');           
        cout << x+1 << ") Input a number: ";
        cin >> num;
    }
    cout << "Your Number: " << num << endl;
    cin.clear();              //Add this
    cin.ignore(200, 'n');    //and this
}

然而,这似乎与过多的cin.clear()cin.ignore()有点复杂。仍然希望有人能给出他们有见地的解决方案。

验证输入的正确方法是测试以确保std::cin没有设置任何标志,然后清除缓冲区(如果有)。

我建议你用这样的东西---

for ( ;; ) { 
    std:: cin << mph;
    if (! std:: cin.good () ) {
        std:: cerr << "Error! ";
        std:: cin.clear ();
        std:: cin.ignore (std:: numeric_limits 
            <std:: streamsize>:: max (), 'n');
    } else break;
} 

对good()的调用告诉您std::cin是否遇到任何错误状态。如果没有,我们只想继续。调用clear()重置cin的状态标志,使其不再处于错误状态。类似地,ignore()刷新缓冲区,直到它到达换行符或流(所有内容)的末尾。这使得其中的无效数据实际上被删除了,所以另一次尝试不会再次读取相同的数据,首先,当您调用运算符<lt;再一次

就我个人而言,我倾向于使用以下片段:

template <class InputType>
void SafeInput (InputType & InputVar, std:: function <bool (InputType &)>
    Predicate) {
  for ( ;; ) {
    std:: cin >> InputVar;
    if (std:: cin.good () && Predicate (InputVar)) return;
    std:: cerr << "Input format error. Please Re-entern";
    std:: cin.clear ();
    std:: cin.ignore (std:: numeric_limits <std:: streamsize>:: max (), 'n');
  }
}

如果你愿意的话,你当然可以自由使用。

就是一个例子

std:: string TheStringToFill {};  
std:: cout << "nYou may enter only the word "cat", but in any case.";
SafeInput <std:: string> (TheStringToFill,
            [] (std:: string Input) -> bool {
              std:: transform (Input.begin (), Input.end(),
                               Input.begin (), :: toupper);
              return (Input.compare ("CAT") == 0);
            } );

或者,更好的是,使用一个数字:

int TheValueToGetInputTo;  
std:: cout << "You may enter any number that is less then ten: ";
SafeInput <int> (TheValueToGetInputTo,
                 [=] (int Input) -> bool {
                   return Input < 10;
                 } );

当然,您可以用命名函数替换任何Lambda,但在这种情况下Lambda较小。