我正在阅读 freopen()
,并意识到如果我们指定stdin / stdout,即使我们使用cin / cout进行编码,该函数也能正常工作 .
研究了一下,我发现了这个链接freopen() equivalent for c++ streams,其中一个用户回答:
来自C标准27.3.1:“对象cin控制与对象stdin关联的流缓冲区的输入,在<cstdio>中声明 . ”所以根据标准,如果我们重定向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输出流stdout相关联 .
这就是它有点令人困惑的地方,因为我也在阅读关于冲洗的事情,并注意到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);
.
2 回答
您在"on purpose"中调用
ios::sync_with_stdio(false)
和cin.tie(0)
的目的是确保(1)CI / O流(stdout
等)与其C对应物(std::cout
等)和(2)不同步以确保stdout
并且stdin
没有绑定(即从stdin
读取并不一定会导致stdout
被刷新) .这就是
fflush(stdout)
在您的示例中不影响std::cout
的原因 . 您已经专门禁用了这样的效果,并且两者可以单独缓冲 .freopen()
对可能与提供的文件句柄同步的任何C流的影响未定义 . 在实践中,可能会有一些共同使用的缓冲区,这解释了您所看到的 - 至少,使用您的编译器/库 . 但是其他实现无法保证这种行为 .我的第一个问题是"why would you want to"?为此目的有一个std::ostream::flush()函数,所以请使用它 .
cout.flush();
.它的原因是"doesn't work"是用
fflush(FILE* f)
刷新的缓冲区与用于std::ostream
的缓冲区不同(或者至少它's not guaranteed that it will be). It'很可能std::ostream::flush()
确实在作为实现的一部分的底层文件对象上调用了fflush(FILE*)
.