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
相关产品推荐
相关产品推荐

