C++ 使用字符串类输入空格时出现 cin 问题

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11462021/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 15:10:10  来源:igfitidea点击:

Issue with cin when spaces are inputted, using string class

c++stringinput

提问by dead beef

I have the following code:

我有以下代码:

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;
}

I noticed that if I put a space in my input for name that it won't give me a chance to input name, and it will view the entry after the space as age. I apologize if this is a newbie mistake, which it probably is. I previously programmed Java and decided I wanted to switch to C++ because it better suits my needs. I also probably format my code weird to your standards, please correct it if you wish to.

我注意到,如果我在名称的输入中输入一个空格,它不会给我输入名称的机会,它会将空格后面的条目视为年龄。如果这是一个新手错误,我深表歉意,这可能是。我之前编写了 Java 并决定切换到 C++,因为它更适合我的需求。我也可能按照您的标准格式化我的代码,如果您愿意,请更正。

Screenshot of console

控制台截图

I've also noticed another error, something I never really had any problems with in Java. I can't figure out how to prevent it from instantly closing down when it finishes processing. I've heard you can use "system.("pause"); but I've also been told to not use it. I'm really confused on what to use. I've heard to use getchar();, but it doesn't seem to do anything.

我还注意到另一个错误,我在 Java 中从未真正遇到过任何问题。我不知道如何防止它在完成处理后立即关闭。我听说你可以使用 "system.("pause"); 但我也被告知不要使用它。我真的很困惑要使用什么。我听说过使用 getchar();,但是它似乎没有做任何事情。

Any help would be greatly appreciated, as I'm a complete beginner when it comes to C++.

任何帮助将不胜感激,因为在 C++ 方面我是一个完整的初学者。

回答by chris

Here's what's happening with the input buffer when you run your program:

以下是运行程序时输入缓冲区发生的情况:

std::cin >> name;

You're waiting for input. When you enter "Ryan Cleary", and press enter, the input buffer contains:

您正在等待输入。当您输入“Ryan Cleary”并按回车键时,输入缓冲区包含:

Ryan Cleary\n

Now your cinreads input as normal, stopping at whitespace, leaving your buffer like this:

现在您cin可以正常读取输入,在空格处停止,像这样离开缓冲区:

 Cleary\n

Note the beginning space, as it stops after reading Ryan. Your first variable now contains Ryan. If, however, you want the full name, use std::getline. It will read until a newline, not just whitespace. Anyway, continuing on:

注意开头的空格,因为它在阅读后停止Ryan。您的第一个变量现在包含Ryan. 但是,如果您想要全名,请使用std::getline. 它将一直读到换行符,而不仅仅是空格。无论如何,继续:

std::cin >> age;

Now you're getting another input. There's already something there, though. It skips the whitespace until it can start reading, leaving the buffer with just:

现在你得到另一个输入。不过,那里已经有东西了。它跳过空白直到它可以开始读取,只留下缓冲区:

\n

Your second variable gets the text Cleary. Note the newline still in the buffer, which brings me to the second part. Replacing system ("pause");in a way that always works is tricky. Your best bet is usually to live with a less-than-perfect solution, or as I like to do, one that isn't guaranteed to do exactly what it says:

您的第二个变量获取 text Cleary。请注意缓冲区中的换行符,这让我进入了第二部分。system ("pause");以一种始终有效的方式进行更换是很棘手的。你最好的选择通常是接受一个不太完美的解决方案,或者像我喜欢的那样,一个不能保证完全按照它所说的去做:

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

Okay, so cin.get()didn't work. How about this:

好吧,所以cin.get()没用。这个怎么样:

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

That works perfectly, but what if you copy-paste it somewhere where the newline isn't left over? You'll have to hit enter twice!

这工作得很好,但是如果你将它复制粘贴到没有换行符的地方怎么办?你必须按两次回车!

The solution is to clear the newline (and anything else) out, and then wait. This is the purpose of cin.sync(). However, as seen in the notes section, it is not guaranteed to clear the buffer out like it says, so if your compiler chooses not to, it can't be used. For me, however, it does exactly that, leaving a solution of:

解决方案是清除换行符(和其他任何东西),然后等待。这是 的目的cin.sync()。但是,如注释部分所示,不能保证像它所说的那样清除缓冲区,因此如果您的编译器选择不这样做,则无法使用它。然而,对我来说,它正是这样做的,留下了一个解决方案:

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

The main bad thing about system("pause");is that you have no idea what program it will run on someone else's computer. They could've changed pause.exeor put one that's found first, and you have no way of knowing. This could potentially ruin their computer due to it being possibly anyprogram.

主要的坏处system("pause");是你不知道它会在别人的电脑上运行什么程序。他们可以更改pause.exe或将找到的放在第一位,而您无从得知。这可能会破坏他们的计算机,因为它可能是任何程序。

回答by Bruno Brant

You should try cin.getline, that way, the stream will be read until the first newline character.

您应该尝试cin.getline,这样,流将被读取,直到第一个换行符。

Ok, bad advice as some people pointed out. You can use std::getlineto read a whole line. Again, the delimiter is the newline, unless informed. To read from cin, you can pass it as the first parameter (and the string as the second).

好吧,正如一些人指出的那样,不好的建议。您可以使用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

(of course, you can omit the std::part from the lines, since you already informed the compiler that you are using the stdnamespace)

(当然,您可以省略行中的std::部分,因为您已经通知编译器您正在使用std命名空间)

回答by phillip Harris

In C++ programming language use getline(cin, name);for string variable input.

在 C++ 编程语言中getline(cin, name);用于字符串变量输入。

Where cincan be any istreamand nameis a string that you want to hold the value.

Wherecin可以是 anyistream并且name是您想要保存值的字符串。