C++-为什么fflush(stdout)不适用于iostream
C++ - Why fflush(stdout) does not work with iostream?
我读到了关于freopen()
的文章,并意识到如果我们为其指定stdin/stdout,即使我们使用cin/cout进行编码,该函数也会工作。
经过一点研究,我发现这个链接freopen()相当于c++流,其中一个用户回答:
来自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)可以工作?也许,这个问题会变得更深入:cin/cout与stdin/stdout的关联扩展到什么程度?
抱歉发了这么长的邮件。我尽量做到简明扼要。
我希望这是可以理解的。
提前谢谢。
附言:我特意放了ios::sync_with_stdio(false);
和cin.tie(0);
。
我的第一个问题是"你为什么要"?有一个std::ostream::flush()
函数用于此目的,因此请使用例如cout.flush();
。
它"不起作用"的原因是用fflush(FILE* f)
刷新的缓冲区与用于std::ostream
的缓冲区不同(或者至少不能保证它会起作用)。std::ostream::flush()
很可能确实在作为实现一部分的底层文件对象上调用了fflush(FILE*)
。
您在"专用"中放入的调用ios::sync_with_stdio(false)
和cin.tie(0)
的目的是确保(1)C I/O流(stdout
等)与其C++对应流(std::cout
等)不同步,以及(2)确保stdout
和stdin
不绑定(即从stdin
读取不一定会导致stdout
被刷新)。
这就是为什么fflush(stdout)
不会影响您的示例中的std::cout
。您已经专门禁用了这种效果,这两者可能会被单独缓冲。
freopen()
对任何可能与提供的文件句柄同步的C++流的影响是未定义的。在实践中,可能有一些常用的缓冲区,这解释了您所看到的情况——至少在编译器/库中是这样。但其他实现并不能保证这种行为。
- FLTK 2.0构建和演示,适用于VS2019的2011年左右的代码库
- "string.h"在构建适用于iOS的qt应用程序中找不到消息
- 为什么 std::erase(std::erase_if) 不是适用于<algorithm>任何容器的模板?
- 为什么这适用于 G++ 而不是 CLANG?
- 为什么不区分大小写适用于 std::unordered_set的 std::hash 函数?
- 声明适用于 auto,但不能显式声明类型?
- 什么是通用运行时组件 #ifdef 适用于Windows(UWP)而不是iOS
- Windows 上的 Cmake 不添加共享库路径(适用于 linux)
- Typedef适用于结构,但不适用于枚举,仅适用于C++
- 为什么函数模板不理解 NULL,但适用于 nullptr
- 链接器读取库,但在其中找不到符号?未解析的外部符号,但仅适用于 Win32 而不是 x64
- Netbeans 8.1(适用于 C/C++)找不到我的编译器(gcc-6.0.0 开发版本)
- random_shuffle() 适用于 Windows,但不能在 Linux 上编译
- C++指针到方法模板推导在面向 x86 时不编译,但适用于 x64
- 不在异常中嵌入std::字符串的规则是否仍然适用于move构造函数
- 移动文件夹Windows c++:适用于Vista及以上版本,不包括XP
- 适用于Android的Qt找不到任何兼容的设备答案找到但不知道如何
- 在Windows 7上不起作用,但它适用于Windows 8 dll。
- 可变参数模板转换为 std::function<R(ARGS...)>适用于 GCC 而不是 MSVC2013,为什么?
- C++11 cmath 函数不在 std 命名空间中,适用于 android NDK w/gcc-4.8 或 clang