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

C语言二进制文件读写异常:加载后字符串写入文本文件出乱码

问题分析与修复方案

我帮你定位到了两个函数里的问题,这就是导致二进制文件加载后写入文本文件出现乱码的根源:

1. saveBin函数的致命错误

你在保存二进制文件时犯了一个关键错误:

fwrite(&stringAll, sizeof(char), (stringLength + 1), myBin);

这里的&stringAll是指向指针的指针,你实际写入二进制文件的不是字符串的内容,而是stringAll这个指针变量本身的内存值(也就是一个地址数字)。当你后续加载这个文件时,读取到的是一堆地址相关的垃圾数据,自然会出现乱码。

正确的写法应该直接传入stringAll(它本身就是字符串的首地址指针):

fwrite(stringAll, sizeof(char), stringLength + 1, myBin);

2. loadBin函数的逻辑与参数问题

这个函数存在两个主要问题:

  • 参数类型不匹配:当文件不存在时,你调用saveBin(&myBin, stringAll),但saveBin的第一个参数是FILE*,你传的却是FILE**(&myBin),这会触发未定义行为,导致文件保存逻辑异常。
  • 缺少有效性检查:在调用fread前,你没有确认myBin是否成功打开(比如调用saveBin后可能还是NULL),直接读取会导致错误。
  • 字符串终止符风险:即使读取成功,如果二进制文件里的内容没有\0终止符,后续操作(比如strlen)会读取到缓冲区外的垃圾数据。

修正后的完整代码

修正后的saveBin函数

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

#define SIZE 10000

void saveBin(char *stringAll) { 
    FILE *myBin = fopen("myBin.bin", "wb"); 
    if (myBin == NULL) { 
        printf("Problem writing file!\n"); 
        exit(-1); 
    }
    size_t stringLength = strlen(stringAll); 
    // 写入字符串实际内容,包含终止符
    fwrite(stringAll, sizeof(char), stringLength + 1, myBin); 
    fclose(myBin); 
} 

修正后的loadBin函数

void loadBin(char *stringAll) { 
    FILE *myBin = fopen("myBin.bin", "rb"); 
    if (myBin == NULL) { 
        // 文件不存在时,初始化空字符串并保存
        stringAll[0] = '\0';
        saveBin(stringAll);
        return;
    }
    // 读取内容到缓冲区,最多读取SIZE+1个字符(包含终止符位置)
    fread(stringAll, sizeof(char), SIZE + 1, myBin); 
    // 强制设置缓冲区末尾为终止符,避免无终止符导致的乱码
    stringAll[SIZE] = '\0';
    fclose(myBin); 
} 

额外说明

  • 我去掉了两个函数的FILE*参数,直接在函数内部打开/关闭文件,避免了参数传递带来的类型错误和逻辑混乱。
  • 增加了stringAll[SIZE] = '\0';,确保无论读取的二进制内容是否包含终止符,字符串都能正确结束,彻底解决乱码风险。

你现在可以测试一下:启动程序添加几个单词,退出后重新启动,加载二进制文件后写入文本文件,应该就能正常显示了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 10:18:25