C语言使用fwrite()写入结构体到txt文件出现乱码问题求助
问题诱因
fwrite()是二进制写入接口,作用是将内存中指定长度的原始二进制数据直接写入文件,不会做任何格式转换:- 你定义的
student结构体中name、regnum是char*指针类型,结构体本身存储的只是字符串的内存地址,不是字符串实际内容,所以你写入文件的是这两个指针的地址值,而非用户输入的姓名、学号文本。 - 结构体中的
int类型age也是以4字节(绝大多数平台)二进制值存储,文本编辑器打开文件时会将所有二进制数据强制按ASCII/UTF-8等文本编码解析,自然就会出现乱码。
- 你定义的
- 即使你将结构体中的指针替换为固定长度
char数组,直接用fwrite写入结构体到.txt后缀的文本文件,也会因为内存对齐产生的填充字节、数值类型的二进制存储逻辑,导致文本编辑器打开后显示乱码。
解决方案
根据你的使用场景选择对应方案:
方案1:生成可直接打开查看的文本文件(符合你使用.txt后缀的需求)
不要使用fwrite,改用fprintf()做格式化写入,逐个将结构体字段转换为文本格式写入文件,修改后代码如下:
#include <stdio.h> #include <cs50.h> typedef struct { char* name; char* regnum; int age; } student; int main() { char *studentName = get_string("What's your name: "); char *studentReg = get_string("Input your Registeration Number: "); int age = get_int("How old are you: "); student newStudent = {studentName, studentReg, age}; FILE *studentinfo = fopen("Student's_Information.txt", "w"); if (studentinfo == NULL) { printf("Could not open file"); return 1; } // 按自定义格式写入字段,可直接用文本编辑器打开查看 fprintf(studentinfo, "姓名:%s\n学号:%s\n年龄:%d\n", newStudent.name, newStudent.regnum, newStudent.age); fclose(studentinfo); return 0; }
方案2:需要存储二进制结构体数据方便后续程序直接读取
如果你的使用场景是后续要用C程序直接读取结构体数据,不需要人工查看文件内容,按以下要求修改:
- 将文件后缀改为
.dat/.bin等二进制文件后缀,避免用文本编辑器打开产生乱码误解 - 不要在结构体中使用
char*指针存储字符串,改为固定长度char数组,保证结构体本身包含全部数据,修改后代码如下:
#include <stdio.h> #include <cs50.h> #include <string.h> typedef struct { char name[32]; char regnum[32]; int age; } student; int main() { char *studentName = get_string("What's your name: "); char *studentReg = get_string("Input your Registeration Number: "); int age = get_int("How old are you: "); student newStudent; // 拷贝字符串到结构体数组,避免越界 strncpy(newStudent.name, studentName, sizeof(newStudent.name) - 1); newStudent.name[sizeof(newStudent.name) - 1] = '\0'; strncpy(newStudent.regnum, studentReg, sizeof(newStudent.regnum) - 1); newStudent.regnum[sizeof(newStudent.regnum) - 1] = '\0'; newStudent.age = age; // 二进制写入指定用wb模式 FILE *studentinfo = fopen("Student's_Information.dat", "wb"); if (studentinfo == NULL) { printf("Could not open file"); return 1; } fwrite(&newStudent, sizeof(student), 1, studentinfo); fclose(studentinfo); return 0; }
内容的提问来源于stack exchange,提问作者Edomobi Frank
相关产品推荐
相关产品推荐

