我正在阅读freopen()
,并意识到如果我们为它指定stdin / stdout,即使我们使用cin / cout进行编码,该函数也能正常工作。
稍微研究一下,我找到了这个链接freopen() equivalent for c++ streams,其中一个用户回答:
来自C ++标准27.3.1:
"对象cin
控制与stdin
中声明的对象<cstdio>
关联的流缓冲区的输入。&#34;
因此,根据标准,如果我们重定向stdin
,它还会重定向cin
。反之亦然cout
。
在CPPReference上也看到了类似的东西:
http://en.cppreference.com/w/cpp/io/cin
http://en.cppreference.com/w/cpp/io/cout
全局对象std :: cout和std :: wcout控制输出到实现定义类型的流缓冲区(派生自std :: streambuf),与标准C输出流标准输出相关联。
那里有点令人困惑,因为我也在阅读有关冲洗的内容,并注意到fflush(stdout)只是简单地使用了cin / cout。
例如,此示例代码不会打印任何内容:
#include <cstdio>
#include <iostream>
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
int n;
cout << "Please, enter a number: \n";
fflush(stdout);
cin >> n;
}
虽然下面的代码将打印到output.txt:
#include <cstdio>
#include <iostream>
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
freopen("output.txt", "w", stdout);
cout << "Some string";
while (true);
}
从第一个示例代码中删除ios::sync_with_stdio(false);
,它的行为符合预期。并且freopen()
无论如何都有效(无论是否有)。
所以问题是:为什么fflush(stdout)不适用于iostream,而freopen(...,stdout)有效?也许,这个问题可以更深入:与stdin / stdout相关的cin / cout扩展名是什么?
对不起,很长的帖子。我试着尽可能详细和简洁。
我希望这是可以理解的。
提前致谢。
P.S。:我故意提出ios::sync_with_stdio(false);
和cin.tie(0);
。
答案 0 :(得分:4)
您“故意”放置的调用ios::sync_with_stdio(false)
和cin.tie(0)
的目的是确保(1)CI / O流(stdout
等)不是与他们的C ++对应物(std::cout
等)和(2)同步以确保stdout
和stdin
没有绑定(即从stdin
读取不一定导致{{ 1}}被刷新)。
这就是为什么stdout
在您的示例中不会影响fflush(stdout)
的原因。您已经专门禁用了这样的效果,并且两者可以单独缓冲。
std::cout
对可能与提供的文件句柄同步的任何C ++流的影响是未定义的。在实践中,可能会有一些共同使用的缓冲区,这解释了您所看到的 - 至少,使用您的编译器/库。但是其他实现并不能保证这种行为。
答案 1 :(得分:3)
我的第一个问题是“你为什么要”?为此目的有一个std::ostream::flush()
功能,所以请使用它,例如cout.flush();
。
它“不起作用”的原因是用fflush(FILE* f)
刷新的缓冲区与用于std::ostream
的缓冲区不同(或者至少它不能保证它会是)。 std::ostream::flush()
很可能会在作为实现一部分的底层文件对象上调用fflush(FILE*)
。