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

C语言用fscanf读取文件存数组触发Segmentation Fault问题求助

段错误(Segmentation Fault)排查与修复

问题场景

朋友备考时编写C代码读取memory.txt文件,执行while (fscanf(f, "%s %d %d", A[i].costruttore, A[i].ns, A[i].costo) != EOF)时持续触发段错误,尝试给A[i].ns和A[i].costo加&符号后问题仍未解决,以下是原代码和文件内容:

原代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define DIM 100
typedef struct
{
    char costruttore[20];
    int ns;
    int costo;
} memoria;

void lettura(memoria A[], int *n)
{
    int i = 0;
    FILE *f;
    f = fopen("memory.txt", "r");
    if( f == NULL ) {
    fprintf(stderr, "Couldn't open %s: %s\n", "memory.txt", strerror(errno));
    exit(1);
}
    while (fscanf(f, "%s %d %d", A[i].costruttore, A[i].ns, A[i].costo) != EOF)
        i++;
    (*n) = i;
    fclose(f);
    for (i = 0; i < (*n); i++)
        printf("%s %d %d\n", A[i].costruttore, A[i].ns, A[i].costo);
}

int main()
{
    memoria A[DIM];
    int n;
    lettura(A, &n);
    return 0;
}

memory.txt内容

PerKele 56 41
AM-Silicon 49 41
JKR 33 50
Atlantic 57 62
JADA 50 50
JKR 40 51
Drast 28 35
SGUZ 73 55
JADA 29 46
FARSTIC 65 30
Drast 41 36
FRoW 48 67
FARSTIC 39 62
Drast 27 44
SGUZ 51 50
Drast 58 60
Liquid 41 71
SWP3 50 63
KRRAM 54 24
YTK 32 60
ALOE 37 57
HAL 53 39
AM-Silicon 59 50
Atlantic 24 42
ALOE 31 46
JADA 38 65
Nikit 48 49
PerKele 68 37
HAL 46 53
TOO 73 60
HAL 31 37
YTK 39 55
Nikit 57 47
FARSTIC 40 47
AM-Silicon 68 52
HAL 50 50
JADA 32 37
FRoW 47 53
SWP3 50 50
FRoW 52 52
JADA 63 58
Liquid 47 46
Drast 36 54
ALOE 44 30
HAL 39 33
Drast 48 41
SWP3 52 56
KRRAM 65 56

问题排查与修复

1. 核心错误:fscanf读取整数未传地址

fscanf读取int类型变量时,必须传递变量的内存地址(即使用&取址符)。原代码中A[i].ns和A[i].costo直接传入,这会把变量的值当作地址传递,导致非法内存访问,触发段错误。如果朋友说加了&仍未解决,大概率是修改位置错误或未保存生效。

2. 循环越界风险:未限制数组下标

当前循环没有检查i是否超过DIM-1,如果文件行数超过100,i会继续递增,访问数组A的越界内存,同样会触发段错误。

3. 返回值判断逻辑错误:不应仅判断!=EOF

fscanf的返回值是成功读取的变量个数,若仅判断!=EOF,当某行格式错误(比如缺少整数)时,fscanf会返回小于3的值但不等于EOF,导致循环一直执行,i不断增大最终越界。正确的判断应该是返回值等于3,确保每行的三个字段都读取成功。

修复后的代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define DIM 100
typedef struct
{
    char costruttore[20];
    int ns;
    int costo;
} memoria;

void lettura(memoria A[], int *n)
{
    int i = 0;
    FILE *f;
    f = fopen("memory.txt", "r");
    if( f == NULL ) {
        fprintf(stderr, "无法打开文件 %s: %s\n", "memory.txt", strerror(errno));
        exit(1);
    }
    // 修复:添加数组边界检查,且判断fscanf返回值为3
    while (i < DIM && fscanf(f, "%s %d %d", A[i].costruttore, &A[i].ns, &A[i].costo) == 3)
        i++;
    (*n) = i;
    fclose(f);
    for (i = 0; i < (*n); i++)
        printf("%s %d %d\n", A[i].costruttore, A[i].ns, A[i].costo);
}

int main()
{
    memoria A[DIM];
    int n;
    lettura(A, &n);
    return 0;
}

修复说明

  • 给A[i].ns和A[i].costo添加&,传递正确的内存地址给fscanf
  • 循环条件增加i < DIM,避免数组越界
  • 将fscanf的返回值判断改为==3,确保每行三个字段都读取成功,避免死循环

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 02:10:16