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

为何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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 22:50:39