2012-07-12 53 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