2014-09-04 177 views
4

我开始C++编程,并且必须做大量的输入验证。我发现这个功能似乎普遍适用,但在某个方面遇到麻烦;如果我输入-90,程序不会给出错误。我的问题是: 1.如何添加输入不能为< = 0的情况? 2.是否有更好的方式来限制用户的输入?也许C++中的库?C++输入验证

感谢您的任何帮助或建议。

#include <ios> // Provides ios_base::failure 
#include <iostream> // Provides cin 

template <typename T> 
T getValidatedInput() 
{ 
    // Get input of type T 
    T result; 
    cin >> result; 

    // Check if the failbit has been set, meaning the beginning of the input 
    // was not type T. Also make sure the result is the only thing in the input 
    // stream, otherwise things like 2b would be a valid int. 
    if (cin.fail() || cin.get() != '\n') 
    { 
     // Set the error state flag back to goodbit. If you need to get the input 
     // again (e.g. this is in a while loop), this is essential. Otherwise, the 
     // failbit will stay set. 
     cin.clear(); 

     // Clear the input stream using and empty while loop. 
     while (cin.get() != '\n') 
      ; 

     // Throw an exception. Allows the caller to handle it any way you see fit 
     // (exit, ask for input again, etc.) 
     throw ios_base::failure("Invalid input."); 
    } 

    return result; 
} 

使用

inputtest.cpp 

#include <cstdlib> // Provides EXIT_SUCCESS 
#include <iostream> // Provides cout, cerr, endl 

#include "input.h" // Provides getValidatedInput<T>() 

int main() 
{ 
    using namespace std; 

    int input; 

    while (true) 
    { 
     cout << "Enter an integer: "; 

     try 
     { 
      input = getValidatedInput<int>(); 
     } 
     catch (exception e) 
     { 
      cerr << e.what() << endl; 
      continue; 
     } 

     break; 
    } 

    cout << "You entered: " << input << endl; 

    return EXIT_SUCCESS; 
} 
+1

用于指定T的有效范围的可选参数? – crashmstr 2014-09-04 12:54:57

+0

您在'getValidatedInput'中的错误处理是错误的。如果输入来自文件(由于重定向)并且文件已结束,该怎么办? – 2014-09-04 12:58:09

+0

'-90'是一个有效的'int',所以你的函数失败会有些令人吃惊......据说,有很多方法可以解析* specific *输入以获得正确性。至于“通用验证”,我甚至不知道为什么你需要这样的功能。阅读输入,检查'cin',你有你的验证... – DevSolar 2014-09-04 12:58:28

回答

1

std::istream::operator >>中的strtolstrtoul定义的,和表兄弟*,不幸全部不约而同地接受甚至是无符号类型减号。

基本上,您所能做的就是接受signed int输入并将结果与​​零比较。 std::cin.setf(std::ios::failbit)人为地引发了一个转换异常,所以您可以对转换函数在错误时的行为进行排序,但这可能不会有太大的帮助。

* operator >>是根据std::num_get定义的,它是按照scanf定义的,它是根据strto*定义的。大家刚刚通过了降压,但是strtoul肯定是有缺陷的。

0
  1. 使用unsigned int作为模板参数。
  2. 只有您可以设置有关什么输入有效和什么不有效的规则。
1

您可以使用函数来验证

template <typename T> 
T getValidatedInput(function <bool(T)> validator) { 
    T tmp; 
    cin >> tmp; 
    if (!validator(tmp)) { 
     throw ios_base::failure("Invalid input."); 
    } 
    return tmp; 
} 

使用

int input = getValidatedInput<int>([] (int arg) -> bool { 
    return arg >= 0; 
}); 
0

我希望这是你以后,它退出的在进入为零,但将显示负数。由于输入catch方法,它引发异常错误。

#include "stdafx.h" 
#include <iostream> 

using namespace std; 

void inputcatch() 
{ 
    cin.clear(); 
    cin.ignore(cin.rdbuf()->in_avail()); 
} 

int main() 
{ 
    int input; 
    bool quit = false; 
    while (!quit) 
    { 
     cout << "Enter number" << endl; 
     cin >> input; 
     if (cin.fail()) 
     { 
      inputcatch(); 
      cout << "incorrect input" << endl; 
     } 
     else if (input == 0) 
     { 
      quit = true; 

     } 
     else 
     { 
      cout << "your number: " << input << endl; 
     } 
    } 
    return 0; 
}