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

C语言(NetBeans)结构体二进制文件读写功能失效求助

我来帮你排查下这个二进制文件读写的问题,看了你的代码后,发现几个关键错误导致了现在的异常:

1. 保存函数写入了错误的数据结构

在saveBinaryCliente函数里,你当前用的是:

res = fwrite(aux, sizeof(CLIENTE), 1, fp);

但aux是ELEMENTO*类型,指向的是包含VEICULO、CLIENTE、ALUGADO和链表指针的整个节点,而你实际需要保存的只是其中的CLIENTE部分。这种错误的写入会把无关的结构体内容和内存地址都写到文件里,导致读取时完全解析错误,出现全0的情况。

正确的写法应该是写入aux->info_cliente:

res = fwrite(&aux->info_cliente, sizeof(CLIENTE), 1, fp);

2. 保存函数的计数逻辑错误

你现在用res变量记录写入结果,但它在循环里会被每次覆盖,最后打印的Saved %i register clientes!只会显示最后一次写入的结果,而不是总条数。应该单独用一个计数器累加成功写入的数量:

int count = 0;
for(aux=iniLista; aux!=NULL; aux=aux->seguinte){
    res = fwrite(&aux->info_cliente, sizeof(CLIENTE), 1, fp);
    if(res == 1) count++;
}
printf("Saved %i register clientes!\n", count);

3. 读取函数用feof判断循环的坑

while (!feof(fp))的写法很容易导致多读一次无效数据——因为feof是在尝试读取失败后才会设置标志位,循环会多执行一次,可能插入空数据。正确的做法是直接判断fread的返回值:

while (fread(&aux, sizeof(CLIENTE), 1, fp) == 1){
    inserirCliente(iniLista, aux);
}

另外你传入&(*iniLista)有点多余,直接传iniLista就行,它已经是二级指针了。

4. 未插入客户时的空文件处理

当链表为空时,saveBinaryCliente的循环不会执行,但wb模式会创建一个空文件。如果不想生成空文件,可以在保存前先判断链表是否为空:

if(iniLista == NULL){
    fclose(fp);
    printf("No clientes to save!\n");
    return 0;
}

修正后的完整函数

保存函数

int saveBinaryCliente(ELEMENTO *iniLista){
    ELEMENTO *aux = NULL;
    FILE *fp = NULL;
    int res=0;
    int count = 0;
    fp = fopen("clientes.dat", "wb");
    if(fp == NULL){
        printf("Erro ao abrir o ficheiro clientes!\n");
        return -1;
    }
    if(iniLista == NULL){
        fclose(fp);
        printf("No clientes to save!\n");
        return 0;
    }
    for(aux=iniLista; aux!=NULL; aux=aux->seguinte){
        res = fwrite(&aux->info_cliente, sizeof(CLIENTE), 1, fp);
        if(res == 1){
            count++;
        }
    }
    fclose(fp);
    printf("Saved %i register clientes!\n", count);
    return 0;
}

读取函数

int readDataCliente(ELEMENTO **iniLista){
    CLIENTE aux;
    FILE *fp = NULL;
    fp = fopen("clientes.dat", "rb");
    if(fp == NULL){
        printf("Error reading file clientes!\n");
        return -1;
    }
    while (fread(&aux, sizeof(CLIENTE), 1, fp) == 1){
        inserirCliente(iniLista, aux);
    }
    fclose(fp);
    return 0;
}

这些修正后,写入的就是纯净的CLIENTE结构体数据,读取时能正确解析,不会再出现全0或无效数据的问题,计数也会准确显示保存的客户数量。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 09:41:50