为何C语言中scanf()会被跳过?附问题代码示例
问题分析与解决方案
你的程序出现scanf被跳过的核心原因是输入缓冲区残留的换行符被%c格式符直接读取,另外代码还存在严重的未初始化指针滥用问题,会导致内存访问错误甚至程序崩溃。
1. 解决scanf("%c")被跳过的问题
当用scanf("%s", ...)读取血型时,用户输入完按下的回车(\n)会留在输入缓冲区。后续的scanf("%c", &choice_2)会直接读取这个残留的换行符,而非等待用户输入,看起来就像跳过了输入步骤。
修复方式:
- 在
%c前添加空格,让scanf自动忽略缓冲区中的空白字符(包括换行、空格、制表符):scanf(" %c", &choice_2); - 也可以用
getchar()手动清空缓冲区,但前者更简洁可靠。
2. 修复未初始化指针的致命错误
你定义的char *blood_group, *spec_conditions, *allergies;均为未初始化的野指针,直接用scanf("%s", &blood_group)会将输入写入随机内存地址,大概率触发程序崩溃或内存损坏。
修复方式:
- 使用固定大小的字符数组,比如
char blood_group[10], allergies[100], spec_conditions[100];(根据需求设置合理大小); - 或者提前动态分配内存,比如
blood_group = malloc(10 * sizeof(char));,记得使用完后调用free释放内存。
修正后的完整代码
#include<stdio.h> #include<stdlib.h> #include<windows.h> #include<string.h> // 用于strcpy函数 int main(void){ char choice_1, choice_2; // 用固定大小字符数组替代未初始化指针,避免内存错误 char blood_group[10], allergies[100], spec_conditions[100]; printf("Enter the patient's medical details.\n"); printf("Enter your blood group: "); // 数组名本身就是地址,无需取地址符& scanf("%s", blood_group); printf("Does the patient have any allergies:(y/n)"); // 加空格忽略缓冲区残留的换行符 scanf(" %c", &choice_2); if (choice_2 == 'y'){ printf("Kindly enter the allergies: "); scanf("%s", allergies); }else{ // 用strcpy将字符串常量复制到数组,不能直接赋值 strcpy(allergies, "No allergies"); } printf("\nDoes the patient have any special conditions:(y/n)"); // 同样用空格处理换行符 scanf(" %c", &choice_1); if (choice_1 == 'y'){ printf("Kindly enter the condition: "); scanf("%s", spec_conditions); }else{ strcpy(spec_conditions, "No special conditions"); } printf("Displaying details...\n"); Sleep(2000); // Windows下Sleep首字母大写,参数为毫秒 system("cls"); printf(" PATIENT DETAILS\n"); // 新增打印信息的代码,验证输入结果 printf("Blood Group: %s\n", blood_group); printf("Allergies: %s\n", allergies); printf("Special Conditions: %s\n", spec_conditions); Sleep(1000); return 0; }
额外注意事项
- Windows平台的休眠函数是
Sleep(首字母大写),参数单位为毫秒,所以原代码的sleep(2)需改为Sleep(2000)才是等待2秒; - 给字符数组赋值字符串常量时必须用
strcpy,不能直接allergies = "No allergies",因为数组名是常量指针,不支持直接赋值; - 用
%s读取字符串时,建议限制读取长度避免缓冲区溢出,比如scanf("%9s", blood_group)(最多读9个字符,留1个位置给字符串终止符\0)。
内容的提问来源于stack exchange,提问作者Overwatch
相关产品推荐
相关产品推荐

