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

使用文件操作时触发Segmentation Fault,请求代码修复支持

修复C语言段错误(Segmentation Fault)的方案

核心错误点分析

  • 空指针非法访问:文件打开失败时(p == NULL或ptrr == NULL),未终止函数就继续执行fgetc(p)、fscanf(ptrr, ...)等操作,直接触发段错误。
  • fscanf参数传递错误:读取int和long long类型时,未传递变量地址,导致写入非法内存区域。例如fscanf(ptrr, "%d", hiree_login[i].age)应该改为fscanf(ptrr, "%d", &hiree_login[i].age)。
  • 数组长度不足:gender[1]仅能存储字符串结束符'\0',无法容纳单个性别字符(如'M'/'F'),写入时会越界破坏内存。
  • 行数统计逻辑缺陷:若文件最后一行无换行符,linec会少统计一行;若每行字段数不匹配,循环读取会超出数组范围。

修复后的完整代码

#include <stdio.h>
#include <stdlib.h>

#define MAX1 50

struct hireeLogin
{
    int age;
    char name[20];
    char gender[2];  // 修改为长度2,容纳字符+结束符
    int uid;
    char skill[20];
    long long int phno;
} hiree_login[MAX1];

void hire_skill()
{
    int linec = 0;
    FILE *p = fopen("/home/suraj/Coding/PBL/Details/hiree.txt", "r");
    if (p == NULL)
    {
        printf("\nFile did not open\n");
        return;  // 文件打开失败直接返回,避免后续非法操作
    }

    // 修正行数统计逻辑,处理最后一行无换行的情况
    char c;
    int has_content = 0;
    while ((c = fgetc(p)) != EOF)
    {
        has_content = 1;
        if (c == '\n')
        {
            linec++;
        }
    }
    if (has_content && c == EOF)
    {
        linec++;  // 最后一行无换行时补统计
    }
    fclose(p);
    printf("\nNumber of lines :\t%d\n", linec);

    // 防止行数超过数组上限
    if (linec > MAX1)
    {
        printf("\nLine count exceeds MAX1, will read only %d lines\n", MAX1);
        linec = MAX1;
    }

    FILE *ptrr = fopen("/home/suraj/Coding/PBL/Details/hiree.txt", "r");
    if (ptrr == NULL)
    {
        printf("\nFile did not open\n");
        return;
    }

    for (int i = 0; i < linec; i++)
    {
        // 数值类型读取时传递地址
        fscanf(ptrr, "%s", hiree_login[i].name);
        fscanf(ptrr, "%d", &hiree_login[i].age);
        fscanf(ptrr, "%s", hiree_login[i].gender);
        fscanf(ptrr, "%d", &hiree_login[i].uid);
        fscanf(ptrr, "%s", hiree_login[i].skill);
        fscanf(ptrr, "%lld", &hiree_login[i].phno);
    }

    for (int i = 0; i < linec; i++)
    {
        printf("\n%s, %d, %s, %d, %s, %lld\n", 
               hiree_login[i].name, hiree_login[i].age, hiree_login[i].gender,
               hiree_login[i].uid, hiree_login[i].skill, hiree_login[i].phno);
    }
    fclose(ptrr);
}

额外优化建议

  1. 单次文件读取完成操作:无需两次打开文件,第一次读取时可直接将内容存入结构体并统计有效行数,减少IO开销。
  2. 添加fscanf返回值检查:判断每次fscanf是否成功读取预期字段数,避免因文件格式错误引发内存异常。
  3. 限制字符串读取长度:使用%19s代替%s读取name和skill,防止输入字符串超过数组长度导致缓冲区溢出。

内容的提问来源于stack exchange,提问作者Suraj G Meharwade

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 21:01:05