为什么 C 使用 5 个字节来 write/fwrite 数字 10,而用 4 个字节来写 9 或 11?
Why does C use 5 bytes to write/fwrite the number 10, but 4 bytes to write 9 or 11?
海湾合作委员会 Windows
#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;
}
如果我将 test1 设置为 10,10
,那么 fwrite 将写入 10 个字节 到文件:0D 0A 00 00 00 0D 0A 00 00 00
(每个 4 字节的 int 将在其前面填充一个 0D 回车 return 字符)
如果我将 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 进行额外填充的情况下将结构写入文件?
您正在以文本模式写作和阅读。
打开带有标志“wb”和“rb”的文件。这会将文件视为二进制文件。
您在 text 模式下打开文件,因此 Windows 每个 '\n'
字符前面都有一个回车符 return .
您应该改为 binary 模式写入(和读取)二进制数据 (fopen(..., "wb")
) -- 这样会更快,并且避免意外(并且还需要只有 8 个字节,这就是 sizeof(struct test)
。
What is so special about the number 10 that requires this padding?
数字10
恰好是换行符('\n'
)的ASCII码。
海湾合作委员会 Windows
#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;
}
如果我将 test1 设置为 10,10
,那么 fwrite 将写入 10 个字节 到文件:0D 0A 00 00 00 0D 0A 00 00 00
(每个 4 字节的 int 将在其前面填充一个 0D 回车 return 字符)
如果我将 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 进行额外填充的情况下将结构写入文件?
您正在以文本模式写作和阅读。
打开带有标志“wb”和“rb”的文件。这会将文件视为二进制文件。
您在 text 模式下打开文件,因此 Windows 每个 '\n'
字符前面都有一个回车符 return .
您应该改为 binary 模式写入(和读取)二进制数据 (fopen(..., "wb")
) -- 这样会更快,并且避免意外(并且还需要只有 8 个字节,这就是 sizeof(struct test)
。
What is so special about the number 10 that requires this padding?
数字10
恰好是换行符('\n'
)的ASCII码。