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

C语言如何从文本文件读取内容到结构体数组?出现段错误怎么解决

段错误核心原因及修改点
  • 野指针访问:原代码中char * pch;仅声明未分配内存,就直接执行strcpy(pch, line_buf)写入内容,属于非法内存访问,这是触发段错误的最直接原因。实际上不需要额外复制行内容,可直接将line_buf传入strtok使用,若要避免修改原line_buf需先给pch分配与行长度匹配的内存。
  • 结构体内存分配错误:给单个person结构体分配内存时,sizeof (people[line_count-1])取的是指针类型的大小(通常为4/8字节),远小于struct person实际占用的内存,后续访问结构体成员会越界,需改为sizeof(struct person)。
  • 空指针未校验:strtok返回NULL时直接执行strcpy会触发崩溃,需在每次复制前先判断pch是否非空。
  • 资源未释放:原代码未关闭打开的文件指针,也未释放临时申请的内存,存在内存泄漏。
修正后可运行代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct person {
    char *name;
    char *phone;
    char *email;
};

int main(void) {
    int i;
    int peopleSize = 0;
    char *pch;
    FILE *f = fopen("input.txt", "r");
    if (f == NULL) return EXIT_FAILURE;
    // 最多存储100条人员信息
    struct person** people = malloc(100 * sizeof(people[0]));
    if (people == NULL) {
        fclose(f);
        return EXIT_FAILURE;
    }

    char *line_buf = NULL;
    size_t line_buf_size = 0;
    int line_count = 0;
    ssize_t line_size;

    // 逐行读取文件
    while ((line_size = getline(&line_buf, &line_buf_size, f)) >= 1) {
        // 去除行尾换行符
        if (line_buf[line_size-1] == '\n') {
            line_buf[line_size-1] = '\0';
            line_size--;
        }
        if (line_size == 0) continue; // 跳过空行

        // 分配结构体内存
        people[line_count] = malloc(sizeof(struct person));
        if (people[line_count] == NULL) break;

        // 拆分字段
        pch = strtok(line_buf, " ");
        if (pch == NULL) {
            free(people[line_count]);
            continue;
        }
        people[line_count]->name = malloc(strlen(pch)+1);
        strcpy(people[line_count]->name, pch);

        pch = strtok(NULL, " ");
        if (pch == NULL) {
            free(people[line_count]->name);
            free(people[line_count]);
            continue;
        }
        people[line_count]->phone = malloc(strlen(pch)+1);
        strcpy(people[line_count]->phone, pch);

        pch = strtok(NULL, " ");
        if (pch == NULL) {
            free(people[line_count]->phone);
            free(people[line_count]->name);
            free(people[line_count]);
            continue;
        }
        people[line_count]->email = malloc(strlen(pch)+1);
        strcpy(people[line_count]->email, pch);

        line_count++;
        if (line_count >= 100) break; // 不超过预先分配的100条上限
    }
    peopleSize = line_count;

    // 打印所有人员信息
    for (i = 0; i < peopleSize; i++) {
        printf("%s\t%s\t%s\n", people[i]->name, people[i]->phone, people[i]->email);
    }

    // 释放内存
    for (i = 0; i < peopleSize; i++) {
        free(people[i]->email);
        free(people[i]->phone);
        free(people[i]->name);
        free(people[i]);
    }
    free(people);
    free(line_buf); // 释放getline分配的内存
    fclose(f); // 关闭文件

    return EXIT_SUCCESS;
}
编译运行说明

使用原编译命令即可正常运行:
gcc -Wall -O2 -o program filename.c
运行后会输出解析后的人员信息,无段错误,所有申请的内存都会正常释放。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 22:57:03