使用struct与fgets时触发Segmentation Fault的问题求助
问题分析与修复方案
核心错误是传入inserisci_libro的是未初始化的野指针,访问野指针指向的内存直接触发Segmentation Fault,以下是具体问题拆解和修复方案:
代码中的关键错误
全局指针未初始化
全局变量libro *libroptr仅声明了指针,未分配有效内存,属于野指针。调用fgets(libroptr->titolo,...)时,相当于访问非法内存,直接触发段错误。main函数内的错误typedef
全局域已经将libro定义为struct libreria的别名,main函数里的typedef struct libreria libro[MAX];属于错误重定义,既没有创建实际的数组变量,还会造成类型混淆,完全无意义。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
相关产品推荐
相关产品推荐

