2012-06-08 57 views
6

據我所知,提取操作符跳過開始處的空白,並在遇到空白或流尾時停止。 noskipws可以用來停止忽略領先的空格。noskipws對cin的影響>>

我有以下程序,我已經使用noskipws。

#include <iostream> 
using namespace std; 

int main() 
{ 
    char name[128]; 

    cout<<"Enter a name "; 
    cin>>noskipws>>name; 
    cout<<"You entered "<<name<<"\n"; 

    cout<<"Enter another name "; 
    cin>>name; 
    cout<<"You entered "<<(int)name[0]<<"\n"; 

    return 0; 
} 

我的查詢是:

  1. 如果我輸入「約翰」作爲第一個輸入,那麼第二CIN >>操作不等待輸入,什麼都不復制到目標即名稱數組。我期望第二個cin >>能夠在至少一個換行符或流結束處傳遞,而不是僅僅將目標字符串設置爲空。這是爲什麼發生?

  2. 當我輸入「John Smith」作爲第一個cin >>語句的輸入時,觀察到同樣的情況。爲什麼第二個cin >>語句不會將空間或「Smith」複製到目標變量?

以下是該程序的輸出:

Enter a name John 
You entered John 
Enter another name You entered 0 


Enter a name John Smith 
You entered John 
Enter another name You entered 0 

謝謝!

+0

我希望你知道你的程序可以產生緩衝很容易溢出。在生產代碼中,不應該使用'std :: cin'來寫入char數組。改用'std :: string'。 – smerlin

+0

這是真的。以上代碼僅用於說明目的。使用cin.width或cin.getline可以避免一些溢出問題,但正如你提到的std :: string將是最好的。我給出了上面的示例代碼,只是爲了展示我想問的問題。 –

回答

10

一個字符串的>>基本算法是:

skip whitespace 
read and extract until next whitespace 

如果使用noskipws,那麼第一步將被跳過。第一次閱讀後,你被定位在一個空白空間中,所以下一個(以及所有下一個)閱讀將立即停止,不提取任何東西。

>>到一個字符串將永遠不會把空格放入字符串。更一般地說,使用>>noskipws是有問題的,因爲空格總是>>的分隔符;按時使用它可能是有意義的,但通常應該在使用後立即重置。 (曾經情況下它可能是有意義使用>>char時。在這種情況下,流總是提取一個字符。)

+0

好的明白了你的觀點。但我仍然感到困惑,爲什麼沒有輸入「John Smith」導致>>操作員在第二次輸入操作中複製「Smith」。爲什麼「Smith」完全從輸入流中消失,即使第二個cin操作沒有等待輸入。 –

+2

@AchintMehta因爲要讀取的下一個字符是空格,而不是''Smith''中的'S'。你告訴它不要跳過空格,所以它不會。然後它輸入但不包括接下來的空白,這是立即的。 '史密斯'不會消失,你只是不讀它。你不能用'>>'讀取它,除了'>>'變成'char',因爲所有其他'>>'將停止在第一個空白處,不提取任何東西,也不提前輸入位置。 –