C语言读取二进制文件存入链表时输出空字符串及乱码数值问题咨询
问题原因分析
- 读写方式不匹配:你以
rb二进制模式打开文件,却使用fscanf(文本格式读取函数)解析内容。fscanf只能识别明文存储的字符串、十进制数字格式,二进制文件中存储的是内存直接导出的字节数据(比如int类型存的是4字节二进制值,不是ASCII数字串),完全不符合fscanf的解析规则,所以读取结果全是无效值,字符串为空、数值乱码都是这个原因导致的。 - 重复读取逻辑错误:循环内连续调用了2次
fscanf,每次循环会尝试读取2组数据,如果你本意是每次循环处理1个条目,这个逻辑本身就是错误的,会跳过一半数据,且读取失败后未做判断直接打印未初始化的变量值,也会输出乱码。 feof使用不规范:feof是在读取操作失败到达文件末尾后才会被置为真,你先判断!feof再执行读取,会导致最后一次读取时已经到达文件末尾,读取操作失败,直接打印未初始化的变量,出现异常值。
正确实现思路
如果你要读取的二进制文件是直接按item结构体的内存布局写入的(比如写入时用fwrite(&结构体变量, sizeof(item), 1, fp)写入),应该用fread直接读取结构体数据,示例修正代码如下:
#include <stdio.h> #include <stdlib.h> #include <string.h> typedef struct list_element { char word[30]; int l1; int l2; struct list_element *next; } item; typedef item *list; int main() { list L; list root = NULL; list *tail = &root; // 用于尾插保持读取顺序,头插逻辑可删除该变量 FILE *f; if ((f = fopen("ImaFile.bin", "rb")) == NULL) { printf("can't open file\n"); exit(-1); } puts("file opened successfully"); item temp; // 每次读1个item大小的数据,读成功才进入处理逻辑 while (fread(&temp, sizeof(item), 1, f) == 1) { printf("read content: word: %s, l1: %d, l2: %d\n", temp.word, temp.l1, temp.l2); // 申请节点存入链表 L = malloc(sizeof(item)); if (L == NULL) { perror("malloc failed"); exit(-1); } memcpy(L, &temp, sizeof(item)); L->next = NULL; *tail = L; tail = &L->next; // 如果要头插可替换上面4行为: // memcpy(L, &temp, sizeof(item)); // L->next = root; // root = L; } fclose(f); // 此处可添加链表遍历代码验证存储结果 return 0; }
补充说明
如果你的ImaFile.bin本身就是明文文本格式,只是后缀名是bin,那你应该把打开模式换成r而不是rb,同时去掉重复的fscanf调用,修改feof的判断逻辑即可。
内容的提问来源于stack exchange,提问作者Ciao
相关产品推荐
相关产品推荐

