You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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;
}

关键修改说明

  1. 调整read_ord参数为结构体指针,直接操作结构体成员,避免指针传递的坑。
  2. 用栈数组替代动态内存分配,省去手动释放步骤,避免内存泄漏。
  3. 新增文件打开状态检查、数组下标限制,提升代码健壮性。
  4. 分割字符串时加入换行符作为分隔符,处理行尾的换行问题。
  5. 使用strncpy替代strcpy,防止字符串过长导致缓冲区溢出。

内容的提问来源于stack exchange,提问作者eriksson543

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 23:33:20