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

使用struct与fgets时触发Segmentation Fault的问题求助

问题分析与修复方案

核心错误是传入inserisci_libro的是未初始化的野指针,访问野指针指向的内存直接触发Segmentation Fault,以下是具体问题拆解和修复方案:

代码中的关键错误

  1. 全局指针未初始化
    全局变量libro *libroptr仅声明了指针,未分配有效内存,属于野指针。调用fgets(libroptr->titolo,...)时,相当于访问非法内存,直接触发段错误。

  2. main函数内的错误typedef
    全局域已经将libro定义为struct libreria的别名,main函数里的typedef struct libreria libro[MAX];属于错误重定义,既没有创建实际的数组变量,还会造成类型混淆,完全无意义。

  3. scanf后残留换行符的隐性问题
    scanf("%i", &libroptr->anno);读取整数后,输入缓冲区会残留换行符,后续fgets会直接读取这个空行,导致genere输入被跳过。

修复后的完整代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#define a 100
#define MAX 200

typedef struct libreria{
    char titolo[a];
    char autore[a];
    int anno;
    char genere[a];
} libro;

int inserisci_libro(libro *libroptr){
    printf("Titolo: \n");
    fgets(libroptr->titolo, a, stdin);
    // 移除fgets读取的换行符
    libroptr->titolo[strcspn(libroptr->titolo, "\n")] = '\0';

    printf("Autore: \n");
    fgets(libroptr->autore, a, stdin);
    libroptr->autore[strcspn(libroptr->autore, "\n")] = '\0';

    printf("Anno: ");
    scanf("%i", &libroptr->anno);
    // 清除scanf残留的换行符
    while(getchar() != '\n');

    printf("Genere: \n");
    fgets(libroptr->genere, a, stdin);
    libroptr->genere[strcspn(libroptr->genere, "\n")] = '\0';

    return 0;
}

int main(){
    // 方式1:栈上创建结构体变量,传入地址
    libro my_libro;
    inserisci_libro(&my_libro);

    // 方式2:动态分配内存(适合多书籍场景)
    // libro *libroptr = malloc(sizeof(libro));
    // if(libroptr == NULL){
    //     perror("malloc failed");
    //     return 1;
    // }
    // inserisci_libro(libroptr);
    // free(libroptr);

    // 验证输入结果
    printf("\n你输入的书籍信息:\n");
    printf("Titolo: %s\n", my_libro.titolo);
    printf("Autore: %s\n", my_libro.autore);
    printf("Anno: %d\n", my_libro.anno);
    printf("Genere: %s\n", my_libro.genere);

    return 0;
}

修复要点说明

  • 内存初始化:要么在栈上创建结构体变量(如libro my_libro;)并传入地址,要么用malloc动态分配内存(记得用完free),避免野指针。
  • 输入缓冲区清理:用while(getchar() != '\n');清除scanf残留的换行符,用strcspn移除fgets读取的换行符,保证输入逻辑正常。
  • 冗余代码移除:删除无用的全局变量i、未使用的头文件math.h和malloc.h(标准C用stdlib.h即可),简化代码结构。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 00:50:13