scanf()后程序终止问题排查:结构体实现新生儿信息录入异常
新生儿信息录入C程序异常分析与解决
问题描述
开发采用结构体实现的新生儿信息录入C程序时,程序在打印“Father age”输入提示后直接终止,程序输出如下:
原代码
#include <stdio.h> #include <stdlib.h> struct father{ char dad_name[50]; int dad_age; }; struct mother{ char mom_name[50]; int mom_age; }; struct baby{ char baby_name[50]; char sex[6]; char birthday[10]; struct father father1; struct mother mother1; }; struct baby *b1; void display(int); int main(){ int baby_num; printf("Enter number of baby that is/are going to input: "); scanf("%d", &baby_num); display(baby_num); printf("\nNEW BORN IN KUANTAN HOSPITAL\n"); for(int i=0; i<baby_num; i++){ printf("\nBaby %d\n", i+1); printf("Baby Name: %s\n", b1[i].baby_name); printf("Sex: %s\n", b1[i].sex); printf("Birthday: %s\n", b1[i].birthday); printf("\nFather name: %s\n", b1[i].father1.dad_name); printf("Father age: %d", b1[i].father1.dad_age); printf("\nMother name: %s\n", b1[i].mother1.mom_name); printf("Mother age: %s\n", b1[i].mother1.mom_age); }; return 0; }; void display(int baby_num){ int temp; b1 = (struct baby*) malloc(baby_num * sizeof(struct baby)); for(int i=0; i<baby_num;i++){ printf("Baby Name: "); scanf("%d", &temp); scanf("%[^\n]", b1[i].baby_name); printf("Sex: "); scanf("%s", b1[i].sex); printf("Birthday: "); scanf(" %s", b1[i].birthday); printf("Father name: "); scanf("%d", &temp); scanf("%[^\n]", b1[i].father1.dad_name); printf("Father age: "); scanf("%d", b1[i].father1.dad_age); printf("Mother name: "); scanf("%[^\n]", b1[i].mother1.mom_name); printf("Mother age: "); scanf(" %d", b1[i].mother1.mom_age); }; }
异常原因分析
scanf参数传递错误(核心崩溃原因)
读取父亲年龄和母亲年龄时,scanf("%d", b1[i].father1.dad_age);和scanf(" %d", b1[i].mother1.mom_age);未传入变量地址。%d格式要求接收int*类型参数,直接传int变量会导致非法内存访问,触发程序崩溃。输入缓冲区处理混乱
用scanf("%d", &temp);清除缓冲区换行的逻辑无效且多余,scanf("%[^\n]")会读取到缓冲区残留的换行符,导致字符串读取异常,干扰后续输入流程。输出格式不匹配
打印母亲年龄时使用%s格式符对应int类型的mom_age,格式不匹配会导致输出乱码或未知行为。
解决方法
修复scanf地址传递问题
读取年龄时必须传入变量地址,修改为:scanf("%d", &b1[i].father1.dad_age); scanf("%d", &b1[i].mother1.mom_age);正确处理输入缓冲区换行符
去掉多余的scanf("%d", &temp);,在scanf("%[^\n]")格式串前加空格,自动跳过缓冲区中的空白字符(包括换行):printf("Baby Name: "); scanf(" %[^\n]", b1[i].baby_name); printf("Father name: "); scanf(" %[^\n]", b1[i].father1.dad_name); printf("Mother name: "); scanf(" %[^\n]", b1[i].mother1.mom_name);修正输出格式
打印母亲年龄时改用%d格式符:printf("Mother age: %d\n", b1[i].mother1.mom_age);优化内存管理(可选)
避免全局指针滥用,将b1改为在main中分配后传递给display函数,并在程序结束后释放内存,防止内存泄漏。
修正后的完整代码
#include <stdio.h> #include <stdlib.h> struct father{ char dad_name[50]; int dad_age; }; struct mother{ char mom_name[50]; int mom_age; }; struct baby{ char baby_name[50]; char sex[6]; char birthday[10]; struct father father1; struct mother mother1; }; void display(struct baby*, int); int main(){ int baby_num; struct baby *b1 = NULL; printf("Enter number of baby that is/are going to input: "); scanf("%d", &baby_num); b1 = (struct baby*) malloc(baby_num * sizeof(struct baby)); if(b1 == NULL){ printf("Memory allocation failed!\n"); return 1; } display(b1, baby_num); printf("\nNEW BORN IN KUANTAN HOSPITAL\n"); for(int i=0; i<baby_num; i++){ printf("\nBaby %d\n", i+1); printf("Baby Name: %s\n", b1[i].baby_name); printf("Sex: %s\n", b1[i].sex); printf("Birthday: %s\n", b1[i].birthday); printf("\nFather name: %s\n", b1[i].father1.dad_name); printf("Father age: %d\n", b1[i].father1.dad_age); printf("Mother name: %s\n", b1[i].mother1.mom_name); printf("Mother age: %d\n", b1[i].mother1.mom_age); }; free(b1); return 0; }; void display(struct baby *b1, int baby_num){ for(int i=0; i<baby_num;i++){ printf("Baby Name: "); scanf(" %[^\n]", b1[i].baby_name); printf("Sex: "); scanf("%s", b1[i].sex); printf("Birthday: "); scanf("%s", b1[i].birthday); printf("Father name: "); scanf(" %[^\n]", b1[i].father1.dad_name); printf("Father age: "); scanf("%d", &b1[i].father1.dad_age); printf("Mother name: "); scanf(" %[^\n]", b1[i].mother1.mom_name); printf("Mother age: "); scanf("%d", &b1[i].mother1.mom_age); }; }
内容的提问来源于stack exchange,提问作者Alpha Chong
相关产品推荐
相关产品推荐

