2013-04-25 50 views
0
#include <iostream> 
using namespace std; 
int main() 
{ 
    int a; 
    do 
    { 
     /* First reset the flag and then clean the buffer*/ 
     cin.ignore(); 
     cin.clear(); 
     /* Input the number from the user*/ 
     cout << "Enter number\n"; 
     cin >> a; 
     /*Diplay appropiate error if the input was wrong*/ 
     if(cin.fail()) 
     { 
      cout << "invalid input \n"; 
     } 
     /*Display the number if the input was valid*/ 
     else 
     { 
      cout << "number entered is : " << a << endl; 
     } 
    } 
    while(cin.fail()); //repeat until the input is correct 
    return 0; 
} 

每當我執行這個程序時,我必須先輸入新行,然後執行cout<<"Enter number\n";需要額外換行字符

背後的原因是什麼?可能的解決方案是什麼?

注:如果沒有cin.ignore()程序進入一個無限循環

+0

你是一個對你的'cin.ignore();'灑一點慷慨。 – 2013-04-25 07:48:05

回答

0

編輯評論如下:

cin.ignore()期待一些輸入和簡單地忽略它。在cout << "invalid input \n";之後,您應該在if聲明中移動此行。

+0

沒有'cin.ignore'代碼進入無限循環 – debal 2013-04-25 07:49:27

+0

因爲你調用cin.fail()兩次!在else語句中,您應該添加一個'break'來退出循環。 – 2013-04-25 07:53:11

+0

@BenoitThiery這是不正確的。您可以隨時調用'cin.fail()'(如果沒有干預輸入,則保證獲得相同的值)。這是他正確的一件事。 – 2013-04-25 07:54:42

0
cin.ignore(); 
    cin.clear(); 
    /* Input the number from the user*/ 
    cout << "Enter number\n"; 
    cin >> a; 

/* Input the number from the user*/ 
    cout << "Enter number\n"; 

    cin.clear(); 
    cin.ignore(); 
    cin >> a; 
+0

其中至少會忽略一個字符,所以如果用戶輸入'「42」',它將顯示'「2」'。 (如果用戶輸入'「abc」',它會在接受輸入之前循環四次。) – 2013-04-25 08:23:28

0

有幾個問題,你在做什麼。第一個 正如Benoit所說:您在輸出提示之前打電話cin.ignore()太早, 。 cin.ignore()將從輸入流中提取 一個字符(除非輸入 流失敗,或遇到文件結尾)。

第二個是,當你循環(比如說,因爲用戶有 進入​​),你叫cin.ignore()復位 錯誤之前,所以這是一個空操作。如果用戶輸入一個數字而不是 ,那麼您將永遠循環,因爲您將被卡在 不良輸入。您應該將cin.clear()放在處理錯誤的if的 分支中。 (當然,這 意味着你需要某種標誌在 do...while測試,因爲錯誤將被你到達那裏的時候 清零,或者,你可以clearignore在循環的頂部,但在if,所以你只能做 他們,如果cin.fail()。)

第三個就是你忽略的一個字符。如果用戶 輸入​​,則在等待輸入之前,它將循環四次(​​加上新的 行)。通常的解決辦法是通過 下一個換行符忽略了:

cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); 

這應該後進行您輸入int(可能 你是否失效,但因爲你是退出,如果你不」 t 失敗,那麼,如果你不這樣做,並不重要)。

最後,在風格兩點:interogating 無處不在的方式輸入是否成功與否是治療流作爲 一個布爾值:

if (!cin) { 
    // error... 
} else { 
    // OK... 
} 

// ... 
} while (!cin); 

我並不是說這是很好的做法(在很多方面,我更喜歡 你的風格),但它是如此無處不在,以致其他任何事情都會導致你的代碼的讀者開始,並問你爲什麼要做 有所不同。

而且我與提示輸入分隔成一個單獨的函數, 和寫類似:

template <typename T> 
std::istream& 
inputWithPrompt(std::istream& source, std::string const& prompt, T& dest) 
{ 
    std::cout << prompt; 
    source >> dest; 
    return source; 
} 

int 
main() 
{ 
    int a; 
    while (!inputWithPrompt(std::cin, "Enter a number:", a)) { 
     std::cin.clear(); 
     std::cin.ignore(std::numeric_limits<std::streamsize>::max, '\n'); 
     std::cout << "Invalid input" << std::endl; 
    } 
    std::cout << "Number entered is: " << a << std::endl; 
    return 0; 
} 

這似乎有很多清潔對我說:循環,直到你成功了,然後做 成功輸出在你離開循環之後。 (這可能是 值得投入的清理代碼,在clear和 一個單獨的功能以及在ignore。如果你輸入使用>>, 你會需要它往往不夠。)