Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/151.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么在空流上调用std::istream::ignore时不返回?_C++_C++11_Std_Iostream - Fatal编程技术网

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

C++ 为什么在空流上调用std::istream::ignore时不返回?,c++,c++11,std,iostream,C++,C++11,Std,Iostream,std::cin是一个全局对象,因此我总是希望在使用它之前将其设置为良好状态。但是,在未使用的cin上调用ignore()时,函数不会返回 请参见下面的示例代码。如果没有用户干预,执行不会到达第8行(cout)。在我的测试中,无论是否使用第二个参数(分隔符,我尝试了“\n”和EOF),此行为都是一致的 我在网上查阅了一些参考资料,但我不明白为什么会发生这种情况 #include <limits> #include <iostream> #include <strin

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();  
}
#包括
#包括
#包括
std::string readInput(){
std::string input=“”;
std::cin.clear();
std::cin.ignore(std::numeric_limits::max(),'\n');

std::cout请参见第二个参数
'\n'
。您正在请求读取小于等于
'\n'
的字符并忽略它们。由于流上没有
'\n'
,这意味着在收到一个字符之前将一直阻塞

希望很清楚,您应该只在知道流上存在
'\n'
时进行此调用

因此,第二个问题的答案是,在使用之前,不要做任何事情,因为流中没有任何数据

清除流的时间是在从流中读取一些数据之后;然后根据您使用的读取操作,您将知道是否有换行符


请注意,没有“清除流中的任何内容”这样的操作(这是有意设计的)。相反,您的操作将类似于“清除行的其余部分”,其中“行”定义为最多下一个换行符;输入将来自使用换行符的文件或用户按Enter键的交互式终端。

请参阅第二个参数
'\n'
。您请求读取最多包含
'\n'
的字符,并忽略它们。因为该参数上没有
'\n'
流,这意味着阻止,直到收到一个

希望很清楚,您应该只在知道流上存在
'\n'
时进行此调用

因此,第二个问题的答案是,在使用之前,不要做任何事情,因为流中没有任何数据

清除流的时间是在从流中读取一些数据之后;然后根据您使用的读取操作,您将知道是否有换行符

请注意,没有“清除流中的任何内容”这样的操作(这是有意设计的)。相反,您的操作将类似于“清除行的其余部分”,其中“行”定义为最多下一个换行符;输入将来自使用换行符的文件,或用户按Enter键的交互式终端。

如中所述:

ignore的行为类似于未格式化的PutFunction。在构造和检查sentry对象后,它将从流中提取字符并丢弃它们,直到出现以下任一情况:[……] 输入序列中的下一个可用字符c是delim,由Traits::eq_int_type(Traits::to_int_type(c),delim)确定。将提取并丢弃分隔符字符。如果delim是Traits::eof()

因此,如果流为空,它将触发对相应流缓冲区的underflow()的调用,因为在您的示例中,ignore正在等待'\n'

注意:当您想确保流缓冲区完全为空时,可以在_avail()中调用cin.rdbuf()->获取仍在等待从输入缓冲区提取的字符数,如果缓冲区为空,则为0。但是,这高度依赖于实现,因为它将在Visual Studio开箱即用的情况下工作。另一方面,对于GCC,您必须调用cin.sync_with_stdio(false)为了拥有内部缓冲,它不会像这样与LLVM一起工作。

如中所述:

ignore的行为类似于未格式化的PutFunction。在构造和检查sentry对象后,它将从流中提取字符并丢弃它们,直到出现以下任一情况:[……] 输入序列中的下一个可用字符c是delim,由Traits::eq_int_type(Traits::to_int_type(c),delim)确定。将提取并丢弃分隔符字符。如果delim是Traits::eof()

因此,如果流为空,它将触发对相应流缓冲区的underflow()的调用,因为在您的示例中,ignore正在等待'\n'

注意:当您想确保流缓冲区完全为空时,可以在_avail()中调用cin.rdbuf()->获取仍在等待从输入缓冲区提取的字符数,如果缓冲区为空,则为0。但是,这高度依赖于实现,因为它将在Visual Studio开箱即用的情况下工作。另一方面,对于GCC,您必须调用cin.sync_with_stdio(false)之前,它将拥有内部缓冲。但它不会像这样与LLVM一起工作