首页 文章

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

提问于
浏览
-1

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

我使用GCC在Linux x64上 .

2 回答

  • 0

    根据您在注释中的说明,您的意图是将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 runtime, but I can' t也给出零填充保证,立即在MSDN上找到证据(这可能是一个很好的问题) . 如果有人知道Windows标准,其他平台和/或C标准的某些版本本身是否提供此保证,则可以改进此答案 .

    当然,如果你在POSIX系统上并且不需要可移植代码,你可以使用ftruncate(),它可以提供相同的保证,甚至不需要做 fwrite() . Windows有SetEndOfFile() but 该函数用未定义的值填充文件的扩展部分,而不是零字节 .

  • 0

    你可能想要这样的东西:

    int i; for (i=0;i<100;++i){fwrite(&zero, 1, 1, fp);}
    

    您不能从指向单个char的指针写入100个字节 .

相关问题