std :: cin 是一个全局对象,因此我总是希望在使用之前将其设置为良好状态。但是,在未使用的 cin 上调用ignore()时,函数不会返回。
请参阅下面的示例代码。没有用户干预,执行不会到达第8行( cout )。在我的测试中,这种行为与第二个参数(分隔符,我已经尝试过'\ n'和EOF)是否一致。
我经历了几个在线参考,但我不明白为什么会这样。
#include <limits>
#include <iostream>
#include <string>
std::string readInput() {
std::string input = "";
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
std::cout << "We never get here..." << std::endl;
std::getline(std::cin, input);
return input;
}
int main() {
std::string foo = readInput();
}
答案 0 :(得分:2)
请参阅第二个参数'\n'
。您要求读取包括'\n'
在内的字符并忽略它们。由于流上没有'\n'
,这意味着要阻止直到收到一个。
希望很明显,只有在知道流上有'\n'
时才应拨打此电话。
所以,你的第二个问题的答案是,在使用之前,什么都不做,因为流上没有数据。
在从中读取一些数据后,清除流的时间是;然后根据您使用的读取操作,您将知道是否有换行符。
请注意,没有这样的操作“清除流上的任何内容”(这是故意设计)。相反,您的操作将是“清除行的其余部分”,其中“行”定义为下一个换行符;并且输入将来自使用行的文件,或者用户按Enter键的交互式终端。
答案 1 :(得分:2)
如documentation中所述:
ignore表现为UnformattedInputFunction。在构造和检查岗哨对象之后,它从流中提取字符并丢弃它们,直到出现以下任何一种情况:[...] 输入序列中的下一个可用字符c是delim,由Traits :: eq_int_type(Traits :: to_int_type(c),delim)确定。提取并丢弃分隔符字符。如果delim是Traits :: eof()
,则禁用此测试
因此,如果流为空,它将触发对相应流缓冲区的下溢()的调用,因为在你的情况下忽略'\ n'。
注意:如果要确保流缓冲区完全为空,可以调用cin.rdbuf() - &gt; in_avail()来获取仍在等待从输入缓冲区中提取的字符数量,因此如果缓冲区为空,则为0。然而,这是高度依赖于实现的,因为它将起作用,例如,使用Visual Studio开箱即用。另一方面,对于GCC,您必须先调用cin.sync_with_stdio(false)才能使自己的内部缓冲。但是,它不适用于这样的LLVM。