2014-10-10 17 views
-1

我剛開始學習C++,之前用Java編碼。下面的代碼從用戶獲取輸入並驗證輸入。第一件要求選民的數量,這必須是一個正數。如果我輸入一個負數,該程序將按照我的預期行事。它打印出錯誤消息並再次請求輸入。但是,如果我輸入任何其他字符,例如任何字母,我會在控制檯中出現無限循環,要求輸入並打印錯誤消息。我究竟做錯了什麼?C++神祕的無限循環

我的代碼:

#include <iostream> 
using namespace std; 

struct dataT { 
    int numOfVoters = -1; 
    float preSpread = -1; 
    float votingError = -1; 
}; 

void getUserInfo() { 
    dataT data; 
    while (data.numOfVoters == -1) { 
     cout << "enter the number of voters" << endl; 
     cin >> data.numOfVoters; 
     if (data.numOfVoters <= 0) { 
      data.numOfVoters = -1; 
      cout << "Invalid entry, please enter a number larger than zero." << endl; 
     } 
    } 
    while (data.votingError == -1) { 
     cout << "enter the percentage spread between candidates" << endl; 
     cin >> data.votingError; 
     if (data.votingError <= 0 || data.votingError >= 1) { 
      data.votingError = -1; 
      cout << "Invalid entry. Enter a number between 0 to 1." << endl; 
     } 
    } 
    while (data.preSpread == -1) { 
     cout << "Enter the precentage spread between the two candidates." << endl; 
     cin >> data.preSpread; 
     if (data.preSpread <= 0 || data.preSpread >= 1) { 
      data.preSpread = -1; 
      cout << "Invalid input. Enter a number between 0 and 1." << endl; 
     } 
    } 
} 

int main() { 
    getUserInfo(); 
    return 0; 
} 

控制檯:

enter the number of voters 
f 
Invalid entry, please enter a number larger than zero. 
enter the number of voters 
Invalid entry, please enter a number larger than zero. 
enter the number of voters 
Invalid entry, please enter a number larger than zero. 
... 
... 
... 
+6

你輸入失敗。你從來沒有檢查輸入失敗,只是有一個無效的值,你認爲在輸入失敗後有意義。 – chris 2014-10-10 16:27:42

+0

相關:http://stackoverflow.com/questions/24504582/test-whether-stringstream-operator-has-parsed-a-bad-type?noredirect=1#comment37965807_24504582 – 2014-10-10 16:29:47

+0

在第一個「WHILE」循環中,你只檢查對於負數,只要它不是負數,你的代碼將接受它,確保做一個轉換int – 2014-10-10 16:30:45

回答

2

如果你編寫cin >> integervariable,但在cin中有字符不能表示一個整數,輸入失敗,!cin成爲真,並且字符保持在那裏,直到你不重置錯誤的輸入狀態並消耗錯誤的字符。

適當的檢查可以

while(integervariable has not good value) 
{ 
    cout << "prompt the user: "; 
    cin >> integervariable; 
    if(!cin) //something wrong in the input format 
    { 
     cin.clear(); //clear the error flag 
     cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); //discard the rubbish 
     cout << "prompt error message \n"; 
    } 
} 
0

if語句總是true,你想要的東西更像:

if (data.votingError < 0 || data.votingError > 1) { 
    ... 

然後data.votingError可以取一個值不同於-1並退出你的循環。

0

std::cin對象每次讀取時都會檢查它是否處於有效狀態。如果你輸入一個char你的程序需要int,那麼你將「打破」輸入流。隨後所有後續調用std::cin將被有效跳過,直到您手動重置輸入流。發生這種情況時,您將永遠無法將值設置爲-1以外的任何值,並且您的if語句始終計算爲true,從而導致無限循環。

另外,您可以通過在所有測試中包含&& cin來檢查故障狀態。如果數據流處於有效狀態,則輸入對象隱式評估爲true;如果數據流處於故障狀態,輸入對象將隱式評估爲false