You need to enable JavaScript to run this app. C语言中如何检查、读取、创建二进制文件存储struct结构体数据
优惠活动
大模型
产品
解决方案
定价
更多

C语言中如何检查、读取、创建二进制文件存储struct结构体数据

C语言实现学校信息结构体二进制读写与启动校验

需求与卡点

开发C语言程序需实现以下启动流程:

  • 程序启动时检查是否存在已存储的历史学校信息结构体数据
  • 无有效历史数据则引导用户录入,录入完成后写入磁盘存储,再进入主流程
  • 有有效历史数据则直接加载到内存数组,跳过录入环节
    开发时为首次接触C语言文件操作,存在两个核心未解决问题:
  • 无法确定main函数中判断“是否存在有效历史数据”的条件写法
  • 不清楚二进制读写的safe(保存)和read(读取)函数实现逻辑

现有代码框架

#define MAX_ESCOLA 5

typedef struct{
    int identificardor;
    char nome_escola[30];
    char localidade_escola[20];
}t_inserir_escola;

void registar_escolas(t_inserir_escola vetor_adicionar_escola[]);
void safe(t_inserir_escola vetor_adicionar_escola[]);
void read(t_inserir_escola vetor_adicionar_escola[]);

int main()
{
    int numero_questionario = 0;
    t_inserir_escola vetor_adicionar_escola[MAX_ESCOLA];
 
    if(/* 待实现判断条件 */)
    {
        registar_escolas(vetor_adicionar_escola);
        safe(vetor_adicionar_escola);
    }else
        printf("\n|dados já inseridos|");

    // 后续主流程预留
    //t_inquerido vetor_inqueridos[MAX_QUESTIONARIO];
    //menu(vetor_inqueridos, numero_questionario, vetor_adicionar_escola, vetor_adicionar_escola);
    return 0;
}

void safe(t_inserir_escola vetor_adicionar_escola[])
{
    // 待实现
}

void read(t_inserir_escola vetor_adicionar_escola[])
{
    // 待实现
}

落地实现方案

所有逻辑基于二进制文件escolas.dat(程序同级目录)实现,无需第三方依赖。

1. 补充常量定义

在现有宏定义下方新增文件路径常量,方便统一修改:

#define FILE_PATH "escolas.dat" // 存储学校数据的二进制文件路径

2. main函数判断逻辑实现

核心思路:不单纯校验文件是否存在,而是同时校验文件大小是否符合预设值,避免损坏/空文件导致的读取异常:

// 替换main中原有if判断的完整逻辑
FILE *fp = fopen(FILE_PATH, "rb");
int need_input = 0;

if (fp == NULL) {
    // 文件打开失败(不存在/无权限),需要重新录入
    need_input = 1;
} else {
    // 文件打开成功,校验文件大小是否合法
    fseek(fp, 0, SEEK_END); // 指针移到文件末尾
    long file_size = ftell(fp); // 获取文件总字节数
    fclose(fp);

    // 合法大小 = 单个结构体大小 * 最大存储学校数
    if (file_size != sizeof(t_inserir_escola) * MAX_ESCOLA) {
        // 大小不匹配,视为无效数据,需要重新录入
        need_input = 1;
    }
}

if (need_input) {
    registar_escolas(vetor_adicionar_escola);
    safe(vetor_adicionar_escola);
} else {
    printf("\n|dados já inseridos|");
    read(vetor_adicionar_escola); // 加载历史数据到内存数组
}

注意:fseek和ftell仅用于计算文件大小,不会修改文件内容;二进制模式打开可以避免Windows平台下换行符转义导致的大小计算偏差。

3. safe保存函数实现

通过fwrite一次性将整个结构体数组写入二进制文件:

void safe(t_inserir_escola vetor_adicionar_escola[])
{
    // 以二进制写入模式打开,覆盖原有内容
    FILE *fp = fopen(FILE_PATH, "wb");
    if (fp == NULL) {
        perror("保存失败"); // 直接打印系统层面的错误原因(磁盘满、无权限等)
        return;
    }
    // fwrite参数:数据起始指针、单个元素大小、元素总个数、文件指针
    fwrite(vetor_adicionar_escola, sizeof(t_inserir_escola), MAX_ESCOLA, fp);
    fclose(fp);
    printf("\n数据保存完成\n");
}

4. read读取函数实现

通过fread一次性将文件内容读入传入的结构体数组:

void read(t_inserir_escola vetor_adicionar_escola[])
{
    FILE *fp = fopen(FILE_PATH, "rb");
    if (fp == NULL) {
        perror("读取失败");
        return;
    }
    // fread参数和fwrite一致,读取的内容直接填充到传入的数组内存中
    fread(vetor_adicionar_escola, sizeof(t_inserir_escola), MAX_ESCOLA, fp);
    fclose(fp);
}

注意:二进制直接读写结构体的前提是,程序在同一编译环境下运行,不同编译器/不同平台的内存对齐规则可能不一致,会导致读取到乱码;普通本地桌面程序使用该方式无兼容性问题。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.11.08 23:15:04