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

C语言如何正确修改二进制文件中struct结构体的offset成员变量

问题根因与修复方案

原代码核心错误

  • 文件打开模式错误:使用wb+打开文件会直接清空原有所有内容,这是文件内容丢失的首要原因,修改已有二进制文件内容需要使用rb+模式。
  • numFiles变量未初始化:既没有从文件头读取原有文件数,反而直接将未初始化的栈垃圾值写回文件头,直接破坏了文件的元数据头。
  • 读写逻辑混乱:外层for循环、内层while循环的嵌套逻辑完全冗余,写入时也没有对应到正确的索引位置,导致结构体内容被错误覆盖。

正确实现逻辑

正确的执行流程应该是:

  1. 用rb+模式打开文件,不清空原有内容
  2. 读取开头4字节得到文件总数numFiles
  3. 遍历每个file结构体的位置,读取整个结构体修改offset后写回,或者直接定位到offset成员的偏移位置写入新值
  4. 操作完成后关闭文件

修复后代码

#include <stdio.h>
// 确保结构体对齐符合28字节的要求,避免编译器自动对齐导致偏移错误
#pragma pack(4)
typedef struct file {
    char name[20];
    int size;
    int offset;
} file;
#define MAX 1024 // 可根据实际需求调整最大值
#pragma pack()

int writeOffsets(char *archiveFile, file list[]) {
    FILE *binFile = fopen(archiveFile, "rb+");
    if (binFile == NULL) {
        perror("fopen failed");
        return -1;
    }

    int numFiles;
    // 第一步:读取文件头存储的文件总数
    if (fread(&numFiles, sizeof(numFiles), 1, binFile) != 1) {
        perror("read numFiles failed");
        fclose(binFile);
        return -1;
    }

    file cur_file;
    // 遍历每个file结构体的位置
    for (int i = 0; i < numFiles; i++) {
        // 读取当前位置的完整file结构体
        if (fread(&cur_file, sizeof(file), 1, binFile) != 1) {
            perror("read file struct failed");
            break;
        }
        // 回退一个结构体长度,准备写入修改后的值
        fseek(binFile, -(long)sizeof(file), SEEK_CUR);
        // 仅更新offset字段,其余字段保持不变
        cur_file.offset = list[i].offset;
        // 写回修改后的结构体
        fwrite(&cur_file, sizeof(file), 1, binFile);
        // 可选:打印调试信息
        printf("第%d个文件offset更新:旧值=%d,新值=%d\n", i, cur_file.offset, list[i].offset);
    }

    fclose(binFile);
    return 0;
}

注意事项

  • 确保传入的list数组长度至少等于文件中存储的numFiles,避免数组越界
  • 如果不需要修改整个结构体,也可以直接定位到offset的偏移位置写入:每个结构体的offset成员相对于结构体起始位置偏移24字节(20字节name+4字节size),所以可以直接计算偏移后写入4字节的offset值,省去读取整个结构体的步骤。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 18:06:06