You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言使用fread读取二进制文件返回0导致循环终止如何解决

问题原因

核心问题是fread的参数使用错误,该函数的原型为:

size_t fread(void *restrict ptr, size_t size, size_t nmemb, FILE *restrict stream);
  • size:单个读取单元的字节大小
  • nmemb:要读取的单元总数量
  • 返回值是成功读取的单元数量,不是字节总数

你代码中sizeof(buffer)已经等于positionX(因为你定义的是unsigned char buffer[positionX],缓冲区总大小就是整个文件的大小),此时第二个参数传sizeof(buffer)、第三个参数传positionX,相当于要求fread读取总大小为positionX * positionX字节的内容,远大于实际文件的大小,自然读取失败返回0。

修复方案

修改fread的参数即可,有两种常用写法:

  • 按字节为单元读取:
// 每个单元1字节,读positionX个单元,返回值是成功读取的字节数
size_t readed = fread(buffer, 1, positionX, file);
  • 按整个缓冲区为单元读取:
// 每个单元大小是整个缓冲区大小,读1个单元,返回值为1表示读取成功
size_t readed = fread(buffer, sizeof(buffer), 1, file);
// 此时遍历内容用positionX作为循环上限即可

另外补充两个优化点:

  • 变长数组(VLA)在栈上分配大内存容易触发栈溢出,文件较大时更推荐用malloc在堆上分配缓冲区,使用完后调用free释放即可
  • 读取完成后记得调用fclose(file)关闭文件句柄,避免资源泄漏
完整修复后代码示例
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
    if (argc < 2)
    {
        printf("Usage: 请传入要读取的文件路径\n");
        return 1;
    }
    FILE *file = fopen(argv[1], "rb");
    if (file == NULL)
    {
        printf("无法打开文件\n");
        return 1;
    }

    fseek(file, 0, SEEK_END);
    long positionX = ftell(file);
    rewind(file);

    printf("文件大小:%ld\n", positionX);
    unsigned char *buffer = malloc(positionX);
    if (buffer == NULL) {
        printf("内存分配失败\n");
        fclose(file);
        return 1;
    }

    size_t readed = fread(buffer, 1, positionX, file);
    printf("成功读取%zu字节\n", readed);

    for(size_t i = 0; i < readed; i++)
    {
        printf("%02x ", buffer[i]);
    }

    free(buffer);
    fclose(file);
    return 0;
}

内容的提问来源于stack exchange,提问作者user1950241

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 05:18:02