2012-07-12 57 views
9

我有以下代碼:問題與CIN時空格輸入,使用string類

的main.cpp

#include <iostream> 
#include <string> 

using namespace std; 

string name; 
string age; 

int main() { 
    cout <<"Name: "; 
    cin >> name; 
    cout << endl; 
    cout <<"Age: "; 
    cin >> age; 
    cout << endl; 
    cout << "Your name is " << name << ", and you are " << age << " years old." << endl; 
    cout << "Press enter to close this application" << endl; 
    getchar(); 
    return 0; 
} 

我注意到,如果我把一個空間,我輸入名稱,它贏了給我一個輸入姓名的機會,並且它會查看年齡之後的空間。我很抱歉,如果這是一個新手的錯誤,這可能是。我之前編寫過Java,並決定改用C++,因爲它更適合我的需求。我也可能將我的代碼格式化爲符合您的標準,如果您願意,請糾正它。

Screenshot of console

我也注意到另一個錯誤,這是我從來沒有真正在Java中有任何問題。我無法弄清楚如何防止它在完成處理時立即關閉。我聽說你可以使用「system。(」pause「);但我也被告知不使用它,我對使用什麼感到困惑,我聽說過使用getchar();但是它似乎並沒有做任何事情。

任何幫助將不勝感激,因爲我是一個初學者,當涉及到C++。

+0

@chris我想選擇你的評論作爲答案,但我真的不認爲它會讓我。感謝您的幫助。你介意重新發布這個還是某個答案,以便我可以選擇它? – 2012-07-12 23:19:48

+0

我決定在您的評論之前做出更詳細的回答。如果你想閱讀它,它就在那裏(希望沒有微妙的錯誤)。 – chris 2012-07-12 23:28:52

+0

呵呵,你的'getchar'不起作用的原因與我的第一個替換'system(「pause」)的例子不起作用的原因是一樣的。它在答案中解釋。 – chris 2012-07-12 23:36:59

回答

13

下面是與所述輸入緩衝器發生當您運行程序:

std::cin >> name; 

您正在等待輸入。當你進入「瑞安克利」,然後按回車,輸入緩衝區包含:

Ryan Cleary\n 

現在你cin讀取輸入正常,在空白停止,留下您的緩衝區這樣的:

Cleary\n 

注因爲它在閱讀Ryan後停止。你的第一個變量現在包含Ryan。但是,如果您想要全名,請使用std::getline。它會一直讀到換行符,而不僅僅是空格。無論如何,繼續:

std::cin >> age; 

現在你正在獲得另一個輸入。不過,那裏已經有些東西了。它會跳過空白,直到它可以開始閱讀,留下緩衝帶剛:

\n 

你的第二個變量獲取文本Cleary。請注意,換行符仍在緩衝區中,這使我可以進入第二部分。以總是有效的方式替換system ("pause");是棘手的。最好的辦法是平時住有低於完美的解決方案,或者我喜歡做的事,一個是不能保證做正是它說:

std::cin.get(); //this consumes the left over newline and exits without waiting 

好了,所以cin.get()沒工作。這個怎麼樣:

std::cin.get(); //consume left over newline 
std::cin.get(); //wait 

這是完美的,但如果你複製粘貼它的地方換行符不被遺留下來?你必須打兩次輸入!

解決方法是清除換行符(和其他任何內容),然後等待。這是cin.sync()的目的。但是,如註釋部分所示,不能保證按照說明清除緩衝區,因此如果編譯器選擇不這樣做,則不能使用它。但對我來說,它正是這麼做的,剩下的一個解決方案:

std::cin.sync(); //clear buffer 
std::cin.get(); //wait 

主要壞事約system("pause");是,你不知道什麼程序,將別人的電腦上運行。他們可能已經改變了pause.exe或者先放一個,然後你就沒有辦法知道了。這可能會毀掉他們的電腦,因爲它可能是任何程序。

+1

謝謝你,一個很好的答案。它向我解釋了很多。我比以前更瞭解C++的cin如何解析輸入。 – 2012-07-12 23:43:04

+0

我在谷歌搜索時遇到了這個問題。一個很好的解釋。謝謝訴很多。 – PingPing 2013-09-04 19:54:32

7

你應該嘗試 cin.getline,這樣一來,流會讀,直到第一個換行符。

好的,壞的意見,有些人指出。您可以使用std::getline閱讀一整行。同樣,分隔符是換行,除非通知。從閱讀210,你可以把它作爲第一個參數傳遞(而字符串作爲第二個參數)。

std::string str; 
std::getline(cin, str); // to read until the end of line 

std::getline(cin, str, ' '); // to read until a space character, for instance 

(當然,你可以從線省略std::一部分,因爲你已經瞭解到,您正在使用的std命名空間編譯)

+0

-1不好的建議。 'std :: getline'既安全又簡單,'cin.getline'不是。 – 2012-07-12 23:12:35

+0

我錯過了OP說他正在使用字符串類的部分。 – 2012-07-12 23:14:55

+0

更正。但無論如何,我不配得到上漲,因爲我只是從評論中借用了答案...... – 2012-07-12 23:20:16