2017-10-13 96 views
0

我是介紹C++計算機科學課程的學生,這是我第一次在這裏發佈。我們剛剛瞭解while循環,儘管賦值不需要它,但我正在嘗試對此賦值進行輸入驗證。該計劃旨在讀取數字列表並找出列表中第一個和最後8個位置的位置。因此,如果我有四個數字(1,8,42,8)的列表,則第一個和最後8個位置是2和4.該組的大小由用戶決定。C++輸入驗證while循環不終止

我試圖做一個while循環,測試以確保用戶輸入的內容實際上是一個數字,但是當我嘗試輸入類似「。」的內容時。或「a」循環無限地繼續並且不終止。我無法找到我的錯誤,並且據我所知,我使用的語法與我的教科書中的語法完全相同。有人能告訴我我的while循環有什麼問題嗎?

int numbers,   //How large the set will be 
    num,    //What the user enters for each number 
    first8position = 0, //The first position in the set that has an 8 
    last8position = 0; //The last position in the set that has an 8 

//Prompt the user to get set size 
cout << "How many numbers will be entered? "; 
cin >> numbers; 

//Loop to get all the numbers of the set and figure out 
//which position the first and last 8 are in 
for (int position = 1; position <= numbers; position++) 
{ 
    cout << "Enter num: "; 
    cin >> num; 

    //If num isn't a digit, prompt the user to enter a digit 
    while (!isdigit(num)) 
    { 
     cout << "Please enter a decimal number: "; 
     cin >> num; 
    } 

    //If num is 8, and first8position still isn't filled, 
    //set first8position to the current position. 
    //Otherwise, set last8position to the current position. 
    if (num == 8) 
    { 
     if (first8position == 0) 
      first8position = position; 
     else 
      last8position = position; 
    } 


} 

//If the set had an 8, print what its position was 
if (first8position != 0) 
    cout << "The first 8 was in position " << first8position << endl; 

//If there was more than one 8, print the last 8 position. 
//Otherwise, the first and last 8 position are the same. 
if (last8position != 0) 
    cout << "The last 8 was in position " << last8position << endl; 
else 
    cout << "The last 8 was in position " << first8position << endl; 

//If there were no 8s, say so. 
if (first8position == 0) 
    cout << "Sorry, no eights were entered."; 

return 0; 

}

+3

相關/欺騙https://stackoverflow.com/questions/19521320/why-do-i-get-an-infinite-loop-if-i-enter-a-letter-rather-than-a - – NathanOliver

+4

你也沒有正確使用'std :: isdigit'。要看它是如何工作的,請看:http://en.cppreference.com/w/cpp/string/byte/isdigit – NathanOliver

回答

1

兩個問題是導致你的無限循環:

首先,cin >> num,試圖在一個整數值讀取。如果用戶輸入類似於a.(不能是積分值的開始)的內容,則不會讀入任何內容,並且a.保留在輸入緩衝區中;因此,每個後續cin >> num將立即失敗(沒有給用戶輸入的東西的機會,因爲a.仍然在輸入緩衝區,並將保持在那裏)。因此,在這種情況下,您必須使用cin中的這些字符,例如通過使用cin.ignore,你將不得不重置在這種情況下設置的failbit

其次,注意,如果isdigit(int c)檢查ASCII - 值c是一個數字,即,如果c >= 48 && c <= 57。因此,您的支票isdigit(num)將會失敗,直到用戶輸入一個介於4857之間的數字。

請參閱以下代碼,演示如何處理輸入故障。希望能幫助到你。

int main() { 

    int num; 
    cin >> num; 
    while (!cin.eof() && cin.fail()) { // failure when extracting an integral value? 
     cout << "not an integral value." << endl; 

     // clear failbit 
     cin.clear(); 

     // remove characters that are still in the input buffer (until next end of line) 
     cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); 

     // next try to read in an integer 
     cin >> num; 
    } 
    if (!cin.eof()) { 
     cout << "juu:" << num << endl; 
    } 
} 
+0

你可以閱讀下一個'num',並用'while(!(cin >> num))'。 – WorldSEnder

+0

@WorldSEnder:它必須是'while(!(cin >> num))',但是當到達EOF時你可能遇到無限循環。這可以通過專門測試'failbit'來避免。 –

+0

你的回答很清楚,很全面。非常感謝! – Kronimiciad