繁体   English   中英

为什么在空流上调用std :: istream :: ignore时不返回?

[英]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();  
}
  1. 为什么在这种情况下ignore()不返回?
  2. 如何使用安全地重置并清空std :: cin?

参见第二个参数'\\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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM