使用std::cin输入带有空格的内容?

216
#include <string>

std::string input;
std::cin >> input;
用户想要输入“Hello World”。但是cin在两个单词之间的空格处失败了。我该如何让cin接收整个Hello World
我实际上是用结构体做这件事,cin.getline似乎不起作用。这是我的代码:
struct cd
{
    std::string CDTitle[50];
    std::string Artist[50];
    int number_of_songs[50];
};

std::cin.getline(library.number_of_songs[libNumber], 250);

这会导致一个错误。有什么想法吗?


39
你不应该编辑你的问题来问新的问题,因为人们已经回答了你原来的问题,现在这些回答看起来脱离了上下文。如果你的原始问题已经被回答了,只需要开始一个新的问题以避免混淆。请注意不要改变原来的意思。 - Pete
经过一点检查,这是显而易见的,但您能否添加一个 library 变量声明,以明确它是类型为 cd 的变量。 - chandsie
这里有很好的东西,不需要删除。 - dukevin
2
在你的更新中,你试图将 getline 赋值给一个 int。当然会失败。 - Ben Voigt
考虑到这个问题的年龄,你现在应该已经知道了,但是你真的在错误地使用结构和数组。你应该有一个结构体,其中包含一个“单一”的CDTitle、一个“单一”的Artist和一个“单一”的number_of_songs。然后再用一个数组(或更好的是一个std::vector)来存储这个结构体。 - Some programmer dude
8个回答

298

它并不会“失败”; 它只是停止读取。它将一个词素标记视为“字符串”。

使用std::getline

#include <string>
#include <iostream>

int main()
{
   std::string name, title;
   
   std::cout << "Enter your name: ";
   std::getline(std::cin, name);
   
   std::cout << "Enter your favourite movie: ";
   std::getline(std::cin, title);
   
   std::cout << name << "'s favourite movie is " << title;
}

注意,这个函数与使用C风格的char缓冲区而非std::stringstd::istream::getline不同。

更新

你编辑后的问题与原来的问题几乎没有关联。

您尝试将数据读入int中,而不是字符串或字符缓冲区。流的格式化操作仅适用于operator<<operator>>。请使用其中之一(并相应地调整多字输入),或在使用getline后进行词法转换为int


7
我更喜欢这个答案,因为我不需要指定字符长度。 - TheWanderer
3
@TheWanderer 确实,这是一个重要的好处。 - Lightness Races in Orbit
@LightnessRacesinOrbit,你能帮忙吗?在打印输出时,这个问题给我多了一个无意义的换行符。 - Anshuman Kumar
1
我正在尝试实现建议的内容,但对我不起作用。它打印出“输入您的姓名:输入您最喜欢的电影”... - Pedro Silveira
使用ws(空格)在getline()中,例如getline(cin >> ws,name);如果数字输入在字符串之前,则由于空格,第一个字符串输入将被忽略。因此,请使用ws,例如getline(cin >> ws,name);#include using namespace std; main(){ int id=0; string name, address; cout <<"Id? "; cin>>id; cout <<"Name? "; getline(cin>>ws, name); cout <<"Address? "; getline(cin>>ws, address); cout <<"\nName: " < - Syed Nasir Abbas
显示剩余2条评论

127

你需要使用cin.getline()

char input[100];
cin.getline(input,sizeof(input));

9
没问题,发生这种情况很正常。C ++并不像我们希望的那样直观易懂。 - Pete
74
为什么要使用 char 缓冲区?已经是2011年了,可以使用更现代的方法。 - Lightness Races in Orbit
5
为什么不使用cin.getline(input, sizeof(input));?此外,你应该检查返回状态吗? - Jonathan Leffler
6
在这篇文章发布时,这是我对最初提出问题的答案(看一下第一条评论,你会发现由于提问者的编辑,上下文已经改变)。无论如何,如果你认为这个答案不好,可以给它点个踩。我承认这可能不是最好的解决方案,但它仍然是一个解决方案。与其问为什么我没有使用某个东西,不如告诉我们为什么应该按照你的方式做。 - Pete
10
你的回答还算不错,不需要被踩。我认为做两个小改动可以改进它。第一个改动是在调用cin.getline()时使用sizeof(input)代替100;这意味着你可以更改输入缓冲区的大小,只需要更改一行而不是两行。第二个改动是通过使用类似于if (!cin.getline(input, sizeof(input))) { ...handle EOF or error... }的代码来测试cin.getline()的返回值,以提醒OP输入操作特别容易受到意外行为的影响。其他答案也需要这样做。 - Jonathan Leffler

77
标准库提供了一个名为ws的输入函数,它可以从输入流中消耗空白字符。你可以像这样使用它:

标准库提供了一个名为ws的输入函数,它可以从输入流中消耗空白字符。你可以像这样使用它:

std::string s;
std::getline(std::cin >> std::ws, s);

6
我认为这是目前最好的答案。我可以将其与上文的 std::cin>> 结合使用。 - Andra
2
到目前为止最佳答案。当在while/for循环中等待输入时,使用std::getline(std::cin, s)会导致非常混乱和中断的输入。这个选项解决了我的问题! - Zlatan Omerović
1
包含 sstream:#include <sstream> - GilbertS

36

Use :

getline(cin, input);

该函数可在

#include <string>

3
这是唯一对我有效的答案。其余的答案都说要使用cin.getline(),但这只会给我一个错误,说该函数不存在。 - blembo
10
@blembo:真的吗?因为我的回答是在三年前发布的,与你所声称的相反,它表达的是完全相同的意思。 - Lightness Races in Orbit
@blembo:如果你的系统上没有cin.getline,那么你肯定做错了什么。很可能是你传递了错误的参数。最好不要因为自己的错误而责怪别人... - Lightness Races in Orbit
@LightnessRacesinOrbit 我理解为什么你的回答可以被视为我的回答的子集(在内容上)。那条评论中提到的问题可能是由于这个线程中回答的顺序和票数不同而导致的。如果一个速读者开始对C风格的getline不满意,然后是你更长的回答(虽然对于关注重点的读者很有用),然后是另一种使用getline的方式,读者最终可能会得出这个回答是它们中的最佳选择的结论,这基本上类似于你的回答,但更简洁。 - Ardent Coder

15

你想在cin中使用.getline函数。

#include <iostream>
using namespace std;

int main () {
  char name[256], title[256];

  cout << "Enter your name: ";
  cin.getline (name,256);

  cout << "Enter your favourite movie: ";
  cin.getline (title,256);

  cout << name << "'s favourite movie is " << title;

  return 0;
}

本例子是从这里获取的。如果需要更多信息和示例,请参考该链接。


13
事实上,你很少需要使用成员函数 getline,这已经过时了。相反,你应该使用可以与 std::string 一起使用的自由函数 getline。顺带一提,cplusplus.com 不是一个推荐的资源。 - Lightness Races in Orbit
2
@Tomalak 为什么不推荐使用 cplusplus.com?我经常用它 :P - dukevin
7
@KevinDuke说:教程可能会误导并且不准确,参考资料中包含许多错误。这些是好资源。 - Lightness Races in Orbit
1
@NickSweeting:是的;使用这个代替。 - Lightness Races in Orbit
2
对于文档链接,cppreference.com是cplusplus.com的有效替代品(两者均为非官方释义)。 - Ben Voigt
显示剩余2条评论

6

如何从输入中读取字符串?

您可以使用std::cin读取以空格为分隔符的单个单词,如下所示:

#include<iostream>
#include<string>
using namespace std;

int main()
{
    cout << "Please enter a word:\n";

    string s;
    cin>>s;

    cout << "You entered " << s << '\n';
}

请注意,这里没有显式的内存管理和固定大小的缓冲区,您也无法溢出。如果您确实需要整行(而不仅仅是单个单词),可以这样做:
#include<iostream>
#include<string>
using namespace std;

int main()
{
    cout << "Please enter a line:\n";

    string s;
    getline(cin,s);

    cout << "You entered " << s << '\n';
}

5

THE C WAY

你可以使用在c语言中的cstdio(stdio.h)库中找到的gets函数:

#include<cstdio>
int main(){

char name[256];
gets(name); // for input
puts(name);// for printing 
}

C++的方式

gets在c++11中已被删除。

[推荐]: 您可以使用在string.h中的getline(cin,name)或在iostream本身中的cin.getline(name,256)

#include<iostream>
#include<string>
using namespace std;
int main(){

char name1[256];
string name2;
cin.getline(name1,256); // for input
getline(cin,name2); // for input
cout<<name1<<"\n"<<name2;// for printing
}

12
很糟糕的建议,“gets” 函数无法安全使用。在C11标准中,它甚至已经被完全删除了。 - Mat

2
我更倾向于使用以下方法获取输入:
#include <iostream>
#include <string>

using namespace std;

int main(void) {
    string name;

    cout << "Hello, Input your name please: ";
    getline(cin, name);

    return 0;
}

实际上,使用一个包含空格字符的字符串而不是定义数组的总长度非常容易。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接