2010-03-26 25 views
8

下面是代碼:問題使用的CIN兩次

string str; 
cin>>str; 
cout<<"first input:"<<str<<endl; 
getline(cin, str); 
cout<<"line input:"<<str<<endl;

其結果是,函數getline從未暫停用戶輸入,因此第二輸出總是空的。我在第一次調用「cin >> str」之後意識到'\ n'仍然存儲在cin中(使用cin.peek()來檢查),它立即結束getline 。解決方案將在第一次使用和第二次使用之間添加一行: cin.ignore(numeric_limits::max(), '\n');

但是,我仍然不明白,爲什麼在第一次調用後留下'\ n'?什麼是流水號& operator >>真的嗎?

+1

一些更多的挖掘揭示描述如何微妙的是固定: 「提取結束時** **旁邊字符是一個有效的空白或空字符,或者給最終文件已達到。「 – 2010-03-26 20:36:15

回答

1

默認情況下,流插入操作符讀取直到它看到空白爲止。您的第一個電話在看到空格,製表符,換行符等時纔會返回。然後需要消耗下一個字符,以便您可以進入下一個字符。

7

\n留在輸入流中,按照operator>>的方式定義爲std::stringstd::string填充了輸入流中的字符,直到找到空白字符(在這種情況下爲\n),此時填充停止,並且空白現在是輸入流中的下一個字符。

您也可以在cin>>str之後立即致電cin.get()以刪除\n。然而,這種特殊的I/O貓有很多種不同的方法。 (就其本身也許是一個很好的問題?)

+5

擺脫尾隨空格字符的更好方法可能是執行'std :: cin >> str >> std :: ws;'。 – sbi 2010-03-26 17:47:05

+1

運行一些測試,意識到它不是如何爲std::string定義的問題。事實上,操作符>>將任何變量所在的流中的換行符留在流中。但是,感謝您開始討論擺脫空白! – 2010-03-26 19:47:52

2

將它們混合正如其他人所說,日問題換行符是從第一次提取中提取出來的。我做的一個解決方案是丟棄流中的所有左側字符:

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

我通常建議只做std :: cin的面向行的輸入。所以,你的代碼可能看起來像這樣:

string str; 
int val; 
// Read an entire line and parse an integer from it 
{ 
    string line; 
    getline(cin, line); 
    istringstream iss(line); 
    iss >> val; 
} 
cout<<"first input:"<<val<<endl; 
getline(cin, str); 
cout<<"line input:"<<str<<endl; 

一定要添加錯誤檢查了。

getline-only方法避免了必須考慮輸入的行緩衝,清除輸入等。如果直接用>>讀取某些內容,如果用戶輸入而不是輸入什麼,輸入不會終止是必需的,但是直到輸入一個標記(通常不需要這種行爲)。

0

也正在尋找最合適的解決方案。該操作員的實施可能會產生問題。讀取整行文本並不總是可接受的,或者不能在一個輸入行中混合不同的類型。

爲了解決問題,當你想從cin讀取一些數據,並且不知道空格最後輸入操作後正確地提取,你可以這樣做:

std::string str; 
std::cin >> std::ws >> str; 

,但你可以」 t使用此命令清除從cin進行的最後一次輸入操作後的換行符號,不影響新輸入,因爲std::ws將消耗所有空格並且不會返回控制權,直到找到第一個非ws字符或EOF,因此按enter鍵不會完成輸入過程。 在這種情況下應該使用

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

哪個更靈活。

P.S.如果在max()函數(如「標識符預期」)中出現錯誤,可能是由某個頭文件中定義的max宏引起的(例如,由Microsoft);這可以通過使用

#undef max