为什么C用5个字节来写/写数字10,而用4个字节来写9或11?

Xua*_*uan 4 c struct fwrite

Windows 上的 GCC

#include <stdio.h>
#include <stdlib.h>

struct test {
    int n1;
    int n2;
};

int main() {
    FILE *f;
    
    f = fopen("test.dat", "w");
    struct test test1 = {10, 10};
    fwrite(&test1, sizeof(struct test), 1, f);
    fclose(f);
    
    struct test test2;
    f = fopen("test.dat", "r");
    while(fread(&test2, sizeof(struct test), 1, f))
        printf("n1=%d n2=%d\n", test2.n1, test2.n2);
    fclose(f);
    
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

如果我将 test1 设置为,10,10则 fwrite 会将10 个字节写入文件:0D 0A 00 00 00 0D 0A 00 00 00

(每个4字节int将在其前面填充0D回车符)

如果我将 test1 设置为,11,11则 fwrite 会将8 个字节写入文件:0B 00 00 00 0B 00 00 00

(正如我所期望的)

如果我将 test1 设置为,9,9则 fwrite 会将8 个字节写入文件:09 00 00 00 09 00 00 00

(正如我所期望的)

如果我将 test1 设置为,9,10则 fwrite 会将9 个字节写入文件:09 00 00 00 0D 0A 00 00 00

9 按预期获得 4 个字节,但 10 被额外的0D字节填充,从而得到 5 个字节。需要这种填充的数字 10 有什么特别之处?为什么较小和较大的数字(8、9、11、12、13、14 等)都不会被填充?我想也许 GCC 将数字 10 与换行符混淆了(换行符是 10 是 acsii),但这并不能解释 fread 如何能够正确地返回数字 10。

如何将结构写入文件而不在数字 10 上获得额外的填充?

Emp*_*ian 11

您以文本模式打开文件,因此在 Windows 上,每个'\n'字符前面都会添加一个回车符。

您应该以二进制模式写入(和读取)二进制数据( fopen(..., "wb")) ——这会快得多,并且可以避免意外(并且也只需要 8 个字节,这就是事实sizeof(struct test))。

需要这种填充的数字 10 有什么特别之处?

该数字10恰好是换行符 ( '\n') 字符的 ASCII 代码。


Rai*_*dex 8

您正在文本模式下写作和阅读。

打开带有标志“wb”和“rb”的文件。这会将文件视为二进制文件。