2013-07-25 201 views
1

C++ 11(即使用C++ 11技術)驗證cin輸入的最佳方式是什麼?我讀過很多其他答案(全部涉及cin.ignore,cin.clear等),但這些方法看起來很笨拙,並導致大量重複的代碼。C++ 11 cin輸入驗證

編輯:通過「驗證」,我的意思是提供了格式良好的輸入,並且它滿足一些特定於上下文的謂詞。

+0

我不知道你是什麼意思通過「驗證」。讀操作可以成功或失敗,你可以很容易地檢查自C++ 98以來。希望你不是想用std :: cin創建一個用戶界面,對嗎? – DanielKO

+0

當然,你並不是暗示在cli程序運行期間要求命令行輸入總是一個壞主意?考慮要求您確認更改(Y/N)的軟件包管理器。如果有人輸入「Q#$ IQGP @ $」,應該怎麼做?可能再問一遍。 –

+0

我不使用cin/cout進行交互(除非它只是「請輸入一行」),這是太多的工作; ncurses和readline是更好的工具。 – DanielKO

回答

1

我發佈我的解決方案的嘗試作爲答案,希望對別人有用。沒有必要指定謂詞,在這種情況下,函數只會檢查格式正確的輸入。當然,我接受建議。

//Could use boost's lexical_cast, but that throws an exception on error, 
//rather than taking a reference and returning false. 
template<class T> 
bool lexical_cast(T& result, const std::string &str) { 
    std::stringstream s(str); 
    return (s >> result && s.rdbuf()->in_avail() == 0); 
} 

template<class T, class U> 
T promptValidated(const std::string &message, std::function<bool(U)> condition = [](...) { return true; }) 
{ 
    T input; 
    std::string buf; 
    while (!(std::cout << message, std::getline(std::cin, buf) && lexical_cast<T>(input, buf) && condition(input))) { 
     if(std::cin.eof()) 
      throw std::runtime_error("End of file reached!"); 
    } 
    return input; 
} 

下面是它的用法的例子:

int main(int argc, char *argv[]) 
{ 
    double num = promptValidated<double, double>("Enter any number: "); 
    cout << "The number is " << num << endl << endl; 

    int odd = promptValidated<int, int>("Enter an odd number: ", [](int i) { return i % 2 == 1; }); 
    cout << "The odd number is " << odd << endl << endl; 
    return 0; 
} 

如果有一個更好的方法,我很開放的建議!

+2

假設這是在一個標題,我建議刪除使用語句或使用指令。另外,你可以將'cin >> input'右移到條件中,代替'cin.fail()'。輸出也可以在那裏保存另一個被欺騙的線。你最好還是通過const ref來獲取你的參數。 – chris

+0

那麼更像我的編輯? –

+0

非常好,是的。 – chris

0

如果驗證你的意思是,當你想要一個int你想知道如果int真正進入了,那麼只是把輸入的if條件:

int num; 

while (!(std::cin >> num)) 
{ 
    std::cout << "Whatever you entered, it wasn't an integer\n"; 
} 

std::cout << "You entered the integer " << num << '\n'; 
+0

我認爲主要觀點是持續到輸入有效的輸入。 – chris

+1

你忘了清零位;如果讀取操作失敗,則表示失敗的位仍然置位,並且將繼續失敗。 – DanielKO

+0

@DanielKO我沒有寫出完整的代碼,只是一個例子來展示廣泛的筆畫。 –