C语言新手内存分配误区:读取文件存结构体输出乱码求助
C语言读取文件到结构体乱码问题排查与修复
问题根源
你的代码出现乱码主要有以下几个核心问题:
- 参数传递错误:
read_ord函数中的surname和lastname是按值传递,函数内对它们的赋值仅修改局部变量,主函数里的surn、lastn完全拿不到有效地址;且主函数中surn、lastn是未初始化的野指针,直接用于strcpy会触发非法内存访问,导致乱码。 - 内存泄漏:
read_ord中malloc的temp没有释放,每次调用都会占用新内存,最终造成内存泄漏。 - 未做错误检查:主函数未判断
fopen是否成功,若文件打不开会直接崩溃;也未限制数组下标,可能导致数组越界。 - 换行符未处理:
fgets读取的行末尾带有换行符,仅用空格分割会让lastname包含换行符,影响输出格式。
修正后的代码
#include <stdlib.h> #include <stdio.h> #include <string.h> #define N 100 struct person { char surname[N]; char lastname[N]; }; _Bool read_ord(struct person *p, FILE* f){ char temp[1000]; // 用栈数组替代malloc,避免手动释放内存 if(fgets(temp, sizeof(temp), f) == NULL){ return 0; // 处理读取失败或文件末尾 } // 加入换行符作为分隔符,去除末尾换行 char *surname = strtok(temp," \n"); char *lastname = strtok(NULL, " \n"); if(surname != NULL && lastname != NULL){ // 用strncpy避免缓冲区溢出,手动添加结束符 strncpy(p->surname, surname, N-1); p->surname[N-1] = '\0'; strncpy(p->lastname, lastname, N-1); p->lastname[N-1] = '\0'; return 1; } else return 0; } int main (){ FILE *infil = fopen("personer.txt", "r"); if(infil == NULL){ // 检查文件是否成功打开 perror("无法打开文件"); return 1; } struct person p[10]; int a = 0; // 限制数组下标,防止越界 while(a < 10 && read_ord(&p[a], infil) == 1){ printf("%s %s\n", p[a].surname, p[a].lastname); a++; } fclose(infil); // 关闭文件释放资源 return 0; }
关键修改说明
- 调整
read_ord参数为结构体指针,直接操作结构体成员,避免指针传递的坑。 - 用栈数组替代动态内存分配,省去手动释放步骤,避免内存泄漏。
- 新增文件打开状态检查、数组下标限制,提升代码健壮性。
- 分割字符串时加入换行符作为分隔符,处理行尾的换行问题。
- 使用
strncpy替代strcpy,防止字符串过长导致缓冲区溢出。
内容的提问来源于stack exchange,提问作者eriksson543
相关产品推荐
相关产品推荐

