cmets 和答案中有很多混乱的术语。 std::cin 是一个对象;它不会做任何事情自己。
从输入流中读取的
函数属于以下两类之一:它们执行格式化输入或未格式化输入。格式化输入函数将从输入流(此处为std::cin)获得的 文本 转换为他们尝试读取的数据类型:
int i;
std::cin >> i; // operator>> reads text and translates it into an integer value
格式化输入函数从跳过空格开始,然后读取字符并翻译它们;当函数遇到对他们正在读取的类型无效的字符时,或者当他们看到空格时,他们会停止。所以在上面的例子中,如果你输入“32”,流提取器会跳过前导空格,读取3和2,看到下面的空格,然后停止读取。存储在i 中的值将是 32。
std::string data;
std::cin >> data;
在这里,如果您输入“Hello, world”,流提取器 (operator>>) 将读取到空格,并将 "Hello," 存储在 data 中。
如果您想读取空白和非空白,您需要一个未格式化的输入函数:
std::string data;
std::getline(std::cin, data);
这里,对getline 的调用从std::cin 读取文本,直到第一个换行符或输入流的末尾。因此,如果您为此代码键入“32”,data 将保存文本 " 32 "。如果您输入“Hello, world”,data 将保留文本 "Hello, world"。
请注意,如果您将格式化的输入函数与未格式化的输入函数混合使用,则必须小心剩余的空格:
int i;
std::string data;
std::cin >> i;
std::getline(std::cin, data);
如果您在一行中输入“32 Hello, world”,i 会得到 32,data 会得到“Hello, world”。
另一方面,如果您键入两行输入,第一行输入“32”,第二行输入“Hello, world”,您将在i 中得到 32,但data 将为空。这是因为流提取器读取了3 和2,然后看到一个换行符,然后停止,将换行符留在输入缓冲区中。 std::getline 然后读取换行符,它也停止了。但它读取了整行:它吞下了换行符。
因此,当您的代码从格式化输入切换到未格式化输入时,您必须处理输入缓冲区中剩余的空白字符。如果您想阅读它们,很好;但如果不这样做,则需要删除它们:
int i;
std::string data;
std::cin >> i;
std::getline(std::cin, data); // read the rest of the line
std::getline(std::cin, data); // read the next line of text
更好的方法是使用std::cin.ignore(42, '\n'); 之类的东西进行清理。 std::ignore 是无格式输入函数;在这个调用中,它最多读取 42 个字符,寻找换行符。它在读取 42 个字符、看到换行符或到达输入结尾时停止读取。这比使用std::getline(std::cin, data) 更好,因为它不会将文本存储到data,如果行的其余部分有很多文本,这可能需要大量调整大小。该调用更常用的形式是将std::numeric_limits<int>::max() 作为大小参数传递;这是一种特殊情况,它对要读取的字符数没有限制。所以std::cin.ignore(std::numeric_limits<int>::max(), '\n'); 会读取字符,直到找到换行符或到达输入的末尾。
int i;
std::string data;
std::cin >> i;
std::cin.ignore(std::numeric_limits<int>::max(), '\n'); // flush the rest of the line
std::getline(std::cin, data); // read the next line of text