c - 为什么 fread() 给出看似随机的数据?

标签 c file fread fseek

我有以下 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/

相关文章:

c - 指向 C 中结构中的结构的指针

c - 我们如何在网格中找到两条权重最大的路线?

database - 使用 inotify 跟踪系统中的所有文件

逐 block 读取/打印文件的 Linux shell 命令

c - 如何检查文本文件中的文本然后存储变量?

r - 将 fread 函数读入的数据转换为 data.frame

c - _mm_sad_epu8 比 _mm_sad_pu8 快

c - Win32 控制台项目问题

javascript - 从 HTML 打开网络文件夹

php - 在文本文件中写入和读取 php 对象?