以二进制模式写入标准输出的最简单方法是啥?

Posted

技术标签:

【中文标题】以二进制模式写入标准输出的最简单方法是啥?【英文标题】:What is the simplest way to write to stdout in binary mode?以二进制模式写入标准输出的最简单方法是什么? 【发布时间】:2013-05-29 02:35:37 【问题描述】:

我一直在尝试找出将二进制数据从 C 程序写入标准输出的最佳方法。它在 Linux 上运行良好,但在 Windows 上编译时遇到问题,因为“\n”被转换为“\r\n”。

是否有一种标准方法可以以某种二进制模式写入标准输出,从而避免换行符转换?如果没有,让 Windows 停止这样做的最简单方法是什么?

我正在使用 GCC 和 MinGW,并使用 fwrite 写信给 stdout

【问题讨论】:

你目前输出的东西怎么样? 你试过用fwrite代替printf吗? 我目前正在使用 fwrite。 【参考方案1】:

你可以使用setmode(fileno(stdout), O_BINARY)

如果您想让它与 Linux 兼容,请将其包装在 ifdef 中。

另请参阅:https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/setmode?view=vs-2017

【讨论】:

freopen(NULL, "wb", stdout) 也可以使用,并且是可移植的C。但是,它可能会产生不需要的截断效果;请参阅pubs.opengroup.org/onlinepubs/9699919799/functions/freopen.html 的应用程序使用部分。对于它的价值,我认为这个文本是错误的;当新文件名为 NULL 时,没有基础的 open 操作,因此关于 O_TRUNC 的文本不适用。 @R.. 你不能在 Windows 中使用 freopenNULL 文件名,它会根据这个调用无效参数处理程序:msdn.microsoft.com/en-us/library/wk2h68td.aspx 和无效参数处理程序的默认行为是使应用程序崩溃。 @Vargas: NULL 不是 freopen 的无效参数,所以我会说这是 MSVCRT 中的错误... 您发布的链接声明实现定义允许重新打开流。我最初的观点是,这不是将流模式设置为二进制的可移植方式。 或者如果“fileno”不起作用 -> 由于 MSDN 文档,原始值:stdin:0、stdout:1、stderr:2。【参考方案2】:

你可以做类似的事情(这是一种跨平台):

FILE *const in = fdopen(dup(fileno(stdin)), "rb");
FILE *const out = fdopen(dup(fileno(stdout)), "wb");
/* ... */
fclose(in);
fclose(out);

或者您可以将write()read() 系统调用直接与fileno(stdin)fileno(stdout) 一起使用。这些系统调用在较低级别上运行并且不进行任何转换。但它们也没有您从 FILE 流中获得的缓冲。

【讨论】:

关于write() 的部分似乎是错误的,我仍然使用它进行换行转换 您很可能不使用系统调用write(),即man -s 2 write。该级别没有文本/二进制模式。

以上是关于以二进制模式写入标准输出的最简单方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章

从 cargo-maven2-plugin 以嵌入式模式启动 tomcat 的最简单方法是啥?

C#中检查硬盘是不是为SSD而不在硬盘上写入任何文件的最简单方法是啥?

将hdf5文件中的uint32数据写入java中的数组的最简单方法是啥?

更新 mnesia 模式的最简单方法是啥?

从 Ruby 中确定 sizeof(double) 和 sizeof(int) 的最简单方法是啥?

执行 linux 程序并通过 C/C++ 中的 stdin/stdout 与其通信的最简单方法