[英]Why does std::istream::ignore not return when called on an empty stream?
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();
}
参见第二个参数'\\n'
。 您正在要求读取不超过'\\n'
字符并忽略它们。 由于流上没有'\\n'
,因此这意味着阻塞直到接收到一个。
希望很明显,仅应在知道流中存在'\\n'
时才进行此调用。
因此,您的第二个问题的答案是,在使用之前, 请勿执行任何操作 ,因为流上始终没有数据。
清除流的时间是从读它的一些数据之后 ; 然后根据您使用的读取操作,您将知道是否有换行符。
请注意,没有这样的操作“清除流中的内容”(这是有意设计)。 相反,您的操作将是“清除行的其余部分”之类的操作,其中“行”被定义为下一个换行符。 而输入将来自使用行的文件或用户按Enter的交互式终端。
如文档中所述:
ignore表现为UnformattedInputFunction。 在构造并检查了哨兵对象之后,它将从流中提取字符并丢弃它们,直到出现以下任何一种情况:[...]输入序列中的下一个可用字符c是delim,由Traits :: eq_int_type确定(特性:: to_int_type(c),delim)。 分隔符字符被提取并丢弃。 如果delim为Traits :: eof(),则此测试被禁用
因此,如果流为空,它将触发对相应流缓冲区的underflow()的调用,因为在您的情况下,忽略正在等待'\\ n'。
注意:当要确保流缓冲区完全为空时,可以调用cin.rdbuf()-> in_avail()以获取仍在等待从输入缓冲区中提取的字符数,如果缓冲区为0,则为0是空的。 但是,这是高度依赖于实现的,因为它可以与现成的Visual Studio一起使用。 另一方面,对于GCC,必须先调用cin.sync_with_stdio(false)才能拥有内部缓冲。 但是,它不适用于这样的LLVM。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.