C语言struct结构体写入文件后读取异常及乱码问题求解
问题根因
- 第一个核心错误:
fwrite/fread传参错误
你定义的Eu1是指向struct eu实例的指针,&Eu1取的是指针变量本身的内存地址,不是结构体实例的地址。你写入的实际是指针变量的内存值+后续越界的随机内存,不是结构体的真实数据。
同一次运行时你打印的仍是原本内存中未被修改的结构体实例内容,所以误以为读写成功,实际上文件里存的根本不是正确的结构体数据,单独读取时自然拿到的是无效值。 - 第二个问题:二进制存储导致文本打开乱码
fwrite是按内存二进制格式直接写入数据,int类型的成员存储的是二进制数值,不是人类可读的文本字符,用文本编辑器打开自然显示乱码,属于二进制文件的正常表现。如果需要生成明文可读的txt文件,应该用fprintf按文本格式输出内容。 - 第三个隐含错误:二进制读写文件的打开模式错误
如果你要走二进制读写的方案,打开文件时需要加b标识,写入用"ab",读取用"rb",避免文本模式下自动转义换行符导致读写偏移错误。
修正方案
方案1:二进制读写(文件不可用文本编辑器直接查看,读写效率高)
修正后的代码如下:
#include <stdio.h> #include <stdlib.h> #include <string.h> struct eu { char name[30]; int age,weight, number; }; int main() { struct eu *Eu1, euptr; Eu1 = &euptr; printf("Name & Surname:"); scanf("%[^\n]", Eu1->name); getchar(); // 吸收输入后的换行符,避免后续scanf读入异常 printf("\n"); printf("Age:"); scanf("%d", &Eu1->age); printf("\n"); printf("Weight(kg):"); scanf("%d", &Eu1->weight); printf("\n"); printf("Telephone number:"); scanf("%d", &Eu1->number); printf("\n\nDisplay: \n"); FILE *outinfo; // 二进制追加模式打开 outinfo = fopen("person.txt", "ab"); if (outinfo == NULL) { fprintf(stderr, "\nSomething went wrong!\n"); return 1; } // 直接传指针Eu1,指向的就是结构体实例的地址 fwrite(Eu1, sizeof(struct eu),1,outinfo); fclose(outinfo); // 二进制读模式打开 outinfo = fopen("person.txt", "rb"); if (outinfo == NULL) { fprintf(stderr, "\nSomething went wrong!\n"); return 1; } // 读的时候也传Eu1,直接把内容读到euptr的内存空间 while(fread(Eu1, sizeof(struct eu), 1, outinfo)) printf ("\n Name:%s\n Age:%d\n Weight:%d\n Tel. Number:%d\n ", Eu1->name, Eu1->age, Eu1->weight, Eu1->number ); fclose (outinfo); return 0; }
方案2:明文文本读写(文件可直接用文本编辑器打开查看)
如果需要生成可读的txt文件,用fprintf写入,fscanf读取即可,代码如下:
#include <stdio.h> #include <stdlib.h> #include <string.h> struct eu { char name[30]; int age,weight, number; }; int main() { struct eu *Eu1, euptr; Eu1 = &euptr; printf("Name & Surname:"); scanf("%[^\n]", Eu1->name); getchar(); printf("\n"); printf("Age:"); scanf("%d", &Eu1->age); printf("\n"); printf("Weight(kg):"); scanf("%d", &Eu1->weight); printf("\n"); printf("Telephone number:"); scanf("%d", &Eu1->number); printf("\n\nDisplay: \n"); FILE *outinfo; outinfo = fopen("person.txt", "a"); if (outinfo == NULL) { fprintf(stderr, "\nSomething went wrong!\n"); return 1; } // 按文本格式写入 fprintf(outinfo, "%s %d %d %d\n", Eu1->name, Eu1->age, Eu1->weight, Eu1->number); fclose(outinfo); outinfo = fopen("person.txt", "r"); if (outinfo == NULL) { fprintf(stderr, "\nSomething went wrong!\n"); return 1; } // 按文本格式读取 while(fscanf(outinfo, "%s %d %d %d", Eu1->name, &Eu1->age, &Eu1->weight, &Eu1->number) == 4) printf ("\n Name:%s\n Age:%d\n Weight:%d\n Tel. Number:%d\n ", Eu1->name, Eu1->age, Eu1->weight, Eu1->number ); fclose (outinfo); return 0; }
内容的提问来源于stack exchange,提问作者Vlad
相关产品推荐
相关产品推荐

