C语言写入结构体到二进制文件后读取非首条记录失败如何解决
问题排查与解决方案
1. 文件内容乱码原因
你使用wb二进制模式直接写入整个结构体对象,结构体中的int类型是直接以二进制值存储而非转换为十进制文本,所以用普通文本编辑器打开会显示乱码,属于二进制存储的正常现象,不是程序错误。
2. 仅能读取第一条记录的核心原因
读写程序的结构体定义不一致,导致单条记录的内存大小不匹配:
- 写入端
struct student的remarks成员长度为10,单条结构体总大小为sizeof(int) + 50 + 10 + 内存对齐填充 - 读取端
struct studentdata的remarks成员长度为50,单条结构体总大小为sizeof(int) + 50 + 50 + 内存对齐填充
读取时你用更大的结构体大小读取文件,第一次fread就会把第一条记录+第二条记录的前半部分全部读入内存,后续读取自然找不到第二条记录的正确起始位置,无法匹配注册号2。
修复方案
步骤1:统一读写两端的结构体定义
手动保证两端结构体的成员类型、长度完全一致,将读取程序的remarks长度改为10,和写入端对齐:
// 读取程序修改结构体定义 struct studentdata { int reg; char name[50],remarks[10]; // 此处从50改为10,和写入端保持一致 }a;
步骤2:修复其他隐藏BUG
- 字符串输入不需要加取地址符:
scanf("%s",a.name);而非&a.name,数组名本身就是首地址 - 文件打开失败后直接终止程序,避免空指针操作:
if(fpr==NULL) { printf("file does not exist"); return; // 新增该行 }
- 标准C语言main函数写法为
int main(),结束前返回return 0;可避免编译器警告 - 写入程序调用
getche读取输入后,建议清空输入缓冲区残留的换行符,避免干扰后续输入
可选优化(生成可读文本文件)
如果需要生成可直接打开查看的文本格式记录,可将二进制读写替换为文本读写:
- 写入时替换
fwrite为:fprintf(fpr, "%d %s %s\n", a.reg, a.name, a.remarks); - 读取时替换
fread为:fscanf(fpr, "%d %s %s", &a.reg, a.name, a.remarks);
对齐结构体定义后重新运行写入程序写入测试数据,再运行读取程序即可正常匹配所有记录。
内容的提问来源于stack exchange,提问作者CHARANA_GS
相关产品推荐
相关产品推荐

