使用字符串类输入空格时出现 cin 问题
Posted
技术标签:
【中文标题】使用字符串类输入空格时出现 cin 问题【英文标题】:Issue with cin when spaces are inputted, using string class 【发布时间】:2012-07-12 23:07:56 【问题描述】:我有以下代码:
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++,因为它更适合我的需要。我也可能按照你的标准格式化我的代码,如果你愿意,请更正它。
我还注意到另一个错误,这是我在 Java 中从未真正遇到过的问题。我不知道如何防止它在完成处理后立即关闭。我听说你可以使用 "system.("pause"); 但我也被告知不要使用它。我真的很困惑该使用什么。我听说使用 getchar();,但是它似乎没有做任何事情。
任何帮助将不胜感激,因为我是 C++ 的初学者。
【问题讨论】:
@chris 我想选择您的评论作为答案,但我真的不认为它会让我这样做。感谢您的帮助。您是否介意重新发布该或其他内容作为答案,以便我选择它? 我决定在您发表评论之前做出更详细的回答。如果您想阅读它,它就在那里(希望没有细微的错误)。 哦,您的getchar
不起作用的原因与我替换system("pause")
的第一个示例不起作用的原因相同。答案中对此进行了解释。
std::cin input with spaces?的可能重复
【参考方案1】:
以下是运行程序时输入缓冲区发生的情况:
std::cin >> name;
您正在等待输入。当您输入“Ryan Cleary”并按回车时,输入缓冲区包含:
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
这很好用,但是如果你将它复制粘贴到没有留下换行符的地方呢?您必须按两次 Enter!
解决方案是清除换行符(和其他任何内容),然后等待。这就是cin.sync()
的目的。但是,正如注释部分所见,不能保证像它所说的那样清除缓冲区,所以如果你的编译器选择不这样做,它就不能被使用。然而,对我来说,它正是这样做的,留下了一个解决方案:
std::cin.sync(); //clear buffer
std::cin.get(); //wait
system("pause");
的主要缺点是您不知道它将在别人的计算机上运行什么程序。他们本可以更改pause.exe
或将找到的放在第一位,而您无法知道。这可能会破坏他们的计算机,因为它可能是任何程序。
【讨论】:
谢谢你,一个很好的答案。它向我解释了很多。我对 C++ 的 cin 如何解析输入比以前有了更多的了解。 我在谷歌搜索时遇到了这个。一个很好的解释。非常感谢。【参考方案2】:你应该试试cin.getline,这样,流将被读取到第一个换行符。
好的,正如一些人指出的那样糟糕的建议。您可以使用std::getline 阅读整行。同样,除非通知,否则分隔符是换行符。要从cin
中读取,您可以将其作为第一个参数(并将字符串作为第二个参数)传递。
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
命名空间)
【讨论】:
-1 不好的建议。std::getline
既安全又简单,cin.getline
则不然。
我错过了 OP 说他使用字符串类的部分。
已更正。但无论如何,我不值得赞成,因为我只是从 cmets 那里借来答案......
@BrunoBrant,它现在包含正确的信息。你努力改变它的事实才是最重要的。
@Cheersandhth.-Alf 为什么 std::getline 比 cin.getline 好?【参考方案3】:
在 C++ 编程语言中,使用getline(cin, name);
进行字符串变量输入。
其中cin
可以是任何istream
,name
是您要保存值的字符串。
【讨论】:
以上是关于使用字符串类输入空格时出现 cin 问题的主要内容,如果未能解决你的问题,请参考以下文章