2008-11-05 87 views
6

我正在學習C++,並且隨着我一起寫小程序。以下就是這樣一個程序:C++中的無限循環

// This program is intended to take any integer and convert to the 
// corresponding signed char. 

#include <iostream> 

int main() 
{ 
    signed char sch = 0; 
    int n = 0; 
    while(true){ 
    std::cin >> n; 
    sch = n; 
    std::cout << n << " --> " << sch << std::endl; 
    } 
} 

當我運行這個程序,並保持投入,在相當小的絕對值,其行爲與預期相同。但是,當我輸入較大的輸入時,例如10000000000,程序會反覆吐出相同的輸出。輸入的某些組合會導致不穩定的行爲。例如:

#: ./int2ch 
10 
10 --> 

10000000000 
10 --> 

10 --> 

10 --> 

10 --> 

該程序吐出「10 - >」直到它死亡。 (使用這種特定的輸入序列,程序的輸出速度變化速度不規律)。我還注意到,大值的輸出由前一個合法輸入以及當前非法輸入的值決定。

發生了什麼事? (我不在意修復這個程序,這很容易,我想理解它。)

回答

13

基本上,您的cin數據流處於失敗狀態,因此在您嘗試讀取數據時會立即返回。重寫你的例子是這樣的:

#include <iostream> 

int main() 
{ 
    signed char sch = 0; 
    int n = 0; 
    while(std::cin >> n){ 
    sch = n; 
    std::cout << n << " --> " << sch << std::endl; 
    } 
} 

cin >> n將參考返回cin,它可以測試在有條件的「良好性」。所以基本上「while(std::cin >> n)」是說「雖然我仍然可以從標準輸入讀取成功,執行以下操作」

編輯:它重複輸出最後輸入的好值的原因是因爲這是最後一個值成功讀取N,失敗的讀取不會改變n的值

編輯:在評論指出,可以清除錯誤狀態,然後再試一次這樣的事情可能會工作,只是忽略壞的數字:

#include <iostream> 
#include <climits> 

int main() { 
    signed char sch = 0; 
    int n = 0; 
    while(true) { 
     if(std::cin >> n) { 
      sch = n; 
      std::cout << n << " --> " << sch << std::endl; 
     } else { 
      std::cin.clear(); // clear error state 
      std::cin.ignore(INT_MAX, '\n'); // ignore this line we couldn't read it 
     } 
    } 
} 
+0

或者,在std :: cin.clear()中引入一個調用,以在下一次循環之前刪除錯誤狀態。 – hark 2008-11-05 21:18:06

3

鑑於你在32位機器上,10000000000是一個太大的數字來表示一個int。根據編譯器的不同,將int轉換爲char也只會給出0..255或-128..127。

+0

實際上這是0..255或-128..127。 :) – unwind 2008-11-05 21:15:33

0

這裏的一個問題是,char的大小爲一個字節,因此可以只保持在-127和128之間的數字。另一方面,int通常是4個字節,並且可以具有更大的值。第二個問題是,即使對於int,您輸入的值也太大。

+0

首先打印「一些奇怪的字符」不是原因,其次char是沒有默認簽名的,這是依賴於編譯器的。它經常*簽名,但不一定是。 – 2008-11-05 21:18:09

5

是的,Evan Teran已經指出了大部分事情。我想添加的一件事(因爲我不能評論他的評論:))是,你必須打電話給istream :: clear 之前調用istream :: ignore。原因是istream :: ignore同樣只會在流仍然處於失敗狀態時拒絕執行任何操作。

+0

謝謝,糾正。你會得到一個upvote;) – 2008-11-05 22:39:39