我有以下 C 代码,它以 rb+
模式打开文件,然后写入 100 个字节的值 0
。当我读取偏移量不是 0 的文件时,我得到 96。这是为什么?
FILE *fp = fopen("myfile", "rb+");
rewind(fp);
char zero = 0;
fwrite(&zero, 1, 100, fp);
char result;
fseek(fp, 1, SEEK_SET);
fread(&result, 1, 1, fp);
printf("%d\n", result);
我在 Linux x64 上使用 GCC。
最佳答案
根据您在评论中的说明,您的意图是将 100 个零字节写入文件。至少有两种甚至可能三种方法可以做到这一点。
第一个是分配一个 100 个零初始化字节的数组,并写入:
char zeroes[100] = { 0 };
fwrite(zeroes, sizeof(char) /* == 1 */, sizeof(zeroes), f);
如果您想写入 10,000 或 10,000,000 个零字节,则这不能很好地扩展。您也可以这样做:
char zero = 0;
for (int i = 0; i < 100; ++i) fwrite(&zero, sizeof(char), 1, f);
这可以更好地扩展,但性能非常差,因为执行单个大写操作总是比执行许多小写操作更有效。相反,您可以查找文件中较靠后的位置,然后仅写入最后一个字节。 On POSIX systems, this is guaranteed用零填充文件早期未写入的部分:
char zero = 0;
fseek(f, 99, SEEK_SET);
fwrite(&zero, sizeof(char) /* == 1 */, 1, f);
我相信 Windows 的 MSVCRT 运行时也提供了零填充保证,但我无法立即在 MSDN 上找到这方面的证据(这可能是一个很好的问题)。如果有人知道 Windows、其他平台和/或 C 标准本身的某些版本是否做出此保证,则可以改进此答案。
当然,如果您使用 POSIX 系统并且不需要可移植代码,则可以使用 ftruncate()
这甚至不需要执行 fwrite()
即可做出相同的保证。 Windows有SetEndOfFile()
但是该函数使用未定义的值填充文件的扩展部分,而不是零字节。
关于c - 为什么 fread() 给出看似随机的数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53689177/