2014-09-04 266 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; 
}