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

C语言fseek()函数使用异常:读取指定结构体结果不符问题排查

问题排查:fread读取指定结构体位置错误

核心原因:写入逻辑的多余偏移操作

你的代码中,每次调用fwrite写入结构体后,额外执行了fseek(fp, sizeof(tools), SEEK_CUR),这会让文件指针在写完一个结构体后再跳过一个结构体的长度。最终文件的存储结构变成:

结构体1 → 空白块(大小等于单个结构体)→ 结构体2 → 空白块 → ... → 结构体100 → 空白块

相当于每个有效结构体之间都间隔了一个空结构体的位置,导致文件实际占用了200个结构体的空间。

当你试图通过fseek(fp, sizeof(tools)*50, SEEK_SET)定位第51个结构体时,实际指向的是第26个有效结构体的位置(前50个偏移单位里,每2个单位对应1个有效结构体:50/2=25,第25+1=26个),这就是你读取到26的原因。

另外纠正一个误解:fwrite执行后会自动移动文件指针,指向写入内容的下一个位置,完全不需要额外调用fseek。

修正后的代码

#include <stdio.h>
#include <stdlib.h>

typedef struct tools {
    int recordno;
    char toolname[50];
    int quantity;
    float cost;
} tools;

void recordprinter(tools a) {
    printf("%d %s %d %f\n", a.recordno, a.toolname, a.quantity, a.cost);
}

int main() {
    FILE * fp;
    
    // 用wb+创建并读写二进制文件,避免旧文件残留数据干扰
    fp = fopen("file.txt", "wb+");
    if (fp == NULL) { // 增加文件打开失败的判断
        perror("Failed to open file");
        return 1;
    }

    tools * a = (tools *)malloc(100 * sizeof(tools));
    if (a == NULL) { // 增加内存分配失败的判断
        perror("Failed to allocate memory");
        fclose(fp);
        return 1;
    }

    // 初始化结构体数组
    for (int i = 0; i < 100; i++) {
        a[i].cost = 0;
        a[i].toolname[0] = 'a';
        a[i].toolname[1] = '\0';
        a[i].quantity = 0;
        a[i].recordno = i + 1;
    }

    // 修正写入逻辑:去掉多余的fseek,fwrite自动移动指针
    for (int i = 0; i < 100; i++) {
        fwrite(a + i, sizeof(tools), 1, fp);
    }

    // 重置文件指针到开头
    fseek(fp, 0, SEEK_SET);

    // 定位到第51个结构体的起始位置(前50个结构体的总长度)
    fseek(fp, sizeof(tools) * 50, SEEK_SET);
    // 读取到a[3]
    fread(a + 3, sizeof(tools), 1, fp);

    recordprinter(a[3]); // 现在会输出51

    // 释放资源
    free(a);
    fclose(fp);
    return 0;
}

额外优化点

  1. 增加了文件打开和内存分配的错误判断,避免程序崩溃
  2. 改用wb+模式打开文件,确保每次运行都是全新的文件内容,避免旧数据干扰
  3. 写入循环也可以简化为一次fwrite写入整个数组,效率更高:
fwrite(a, sizeof(tools), 100, fp);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 10:46:19