You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

fwrite写入stdout出现额外0x0D字节插入的技术问题咨询

fwrite到stdout时出现额外0x0D字节的原因及解决方法

你遇到的这个问题其实是Windows系统下C标准库流模式的典型“坑”——标准输出流stdout默认处于文本模式,而不是二进制模式,这导致换行符被自动转换,最终在重定向生成的文件中多出了0x0D字节。

问题原因分析

  • Windows系统中,C标准库的文件流分为文本模式和二进制模式:
    • 文本模式下,写入\n(0x0A)时,系统会自动将其转换为Windows换行格式\r\n(0x0D 0x0A);读取时则反向转换。
    • 二进制模式下,数据会原封不动地读写,不会做任何字符转换。
  • 你写入file.txt时使用了fopen("file.txt", "wb")的wb标志(二进制写入),所以数据完全和原文件一致;但stdout默认是文本模式,即使你用fwrite写入二进制数据,只要流是文本模式,Windows就会自动处理换行符。
  • 当你用program.exe > stdout.txt重定向输出时,stdout的文本模式依然生效,所以输出到文件的过程中,每个0x0A前都被插入了0x0D,最终出现3个额外字节。

验证你的测试结果

你提到把代码第16行true改为false后,程序输出三个偏移位置:

6ec : d, a
c68 : d, a
ecc : d, a

这正好对应原文件original.txt中三个0x0A的位置——stdout.txt里这些位置的字节变成了0x0D,而原数据是0x0A,完全符合文本模式下的换行符转换规则。

解决方法:将stdout设置为二进制模式

要让stdout以二进制模式输出,需要在写入数据前修改流的模式。在Windows下可以使用_setmode函数(需要包含对应头文件),同时为了跨平台兼容,我们可以加上条件编译:

修改你的代码,在fwrite(&read_data[0], 1, 0x1000, stdout);之前添加以下代码:

#ifdef _WIN32
#include <io.h>
#include <fcntl.h>
// 将stdout设置为二进制模式
_setmode(_fileno(stdout), _O_BINARY);
#endif

修改后,再执行program.exe > stdout.txt,生成的stdout.txt就会和file.txt、原文件完全一致,不会再有额外的0x0D字节。

补充说明

  • Linux/macOS等类Unix系统没有文本模式和二进制模式的区别,所有流默认都是二进制模式,所以在这些系统上不会出现这个问题。
  • 如果你需要保证跨平台的二进制输出一致性,添加上述条件编译代码是最佳实践。

内容的提问来源于stack exchange,提问作者Federal_Reserve

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 07:26:18