这个小的printf循环似乎无处发出一个额外的字节,为什么呢?

mtM*_*ijn 6 c printf stdio

当我使用Windows命令行(即test.exe > test.txt)运行该自包含程序时,由于我无法理解的原因,它会发出一个额外的字节。

#include <stdio.h>

int main() {
    int N = 50;
    for (int i = 0; i < N; ++i)
        printf("%c%c%c", (int)(i / (float)N * 255), 0, 255);
}
Run Code Online (Sandbox Code Playgroud)

人们可能希望test.txt拥有150个字节,但是却有151个字节。用十六进制编辑器查看它,您可以看到:

0000 ff05 00ff 0d0a 00ff 0f00 ff14 00ff     
1900 ff1e 00ff 2300 ff28 00ff 2d00 ff33
00ff 3800 ff3d 00ff 4200 ff47 00ff 4c00
ff51 00ff 5600 ff5b 00ff 6000 ff66 00ff
6b00 ff70 00ff 7500 ff7a 00ff 7f00 ff84
00ff 8900 ff8e 00ff 9300 ff99 00ff 9e00
ffa3 00ff a800 ffad 00ff b200 ffb7 00ff
bc00 ffc1 00ff c600 ffcc 00ff d100 ffd6
00ff db00 ffe0 00ff e500 ffea 00ff ef00
fff4 00ff f900 ff
Run Code Online (Sandbox Code Playgroud)

循环的第三次迭代似乎是引发四个字节的罪魁祸首:0d0a00ff。我一生无法弄清楚为什么会发生这种情况。我用Visual Studio 2015对此进行了编译,以防万一。

mol*_*ilo 5

(int)(2 / (float)5 * 255) 是10,这是换行符的ASCII表示形式,Windows会将其转换为其常规CRLF表示形式。

freopen据我所知,没有办法避免这种行为(在Windows上是受限制的),但是看到要写入二进制数据时,使用文本格式功能printf和标准输出可能不是理想的方法。

  • 视窗!我花了10分钟进行复制,几乎把头发拔了!当然,我已经很久没有为Windows编码了…… (2认同)
  • Windows无法完成此操作。它是C运行时库,用于将C约定映射到printf(“ hello world \ n”)样式的OS行结尾。fopen()具有模式参数的基本原因。和freopen()可以将stdout更改为二进制模式。 (2认同)