使用字符串类输入空格时出现 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 可以是任何istreamname 是您要保存值的字符串。

【讨论】:

以上是关于使用字符串类输入空格时出现 cin 问题的主要内容,如果未能解决你的问题,请参考以下文章

如何在 C++ 中使用 cin 将所有空格读入字符串?

c++利用cin.get()输入带空格的一串数据【追加悬赏】

C++ cin 空格问题

依旧是输入输出(存字符矩阵,空格,换行)

如何限制字符输入“cin”只得到一个字符串

cin, getline() 与 get() 的区别