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

C语言程序中scanf读取oper时出现命令跳过问题求助

医院费用计算C程序的输入异常问题分析

问题概述

编写的医院费用计算C程序在运行时,输入手术费变量oper环节出现输入被“跳过”的异常,此前还遇到char类型变量agree被错误识别为int的问题。以下是原程序代码、异常代码段及运行结果:

原程序代码

#include <stdio.h>

int main()
{
  int inpa, med, oper, day, total;
  char agree;
  

  printf("                     Bach Mai Hospital");
  printf("\n\nHello, please enter your fee and we will calculate\npayment based on your insurance\n");
  printf("How many days have you been in the hospital ");
  scanf("%d", &day);
  printf("How much is your medicine fee ");
  scanf("%d", &med);

  printf("Have you undergone surgery (Yes or No)");
  scanf("%s", &agree);
  switch(agree){
  case 'Y':
    printf("Enter your surgery fee ");
    scanf(" %d", &oper);
    break;
  case 'N':
    oper = 0;
  break;
  };
  printf("%s", agree);

  inpa = day * 15000;
  printf("Your total fee\n");
  printf("Inpatient fee: %-10d x 15000 = %d\n", day, inpa);
  printf("Medicine fee: %-10d\n", med);
  printf("Surgery fee: %-10d\n", oper);
  total = inpa + med + oper;
  printf("\n\nYou pay: %d\n", total);

  return 0;

}

异常代码段

printf("Enter your surgery fee ");
scanf(" %d", &oper);

程序执行结果

Bach Mai Hospital

Hello, please enter your fee and we will calculate
payment based on your insurance
How many days have you been in the hospital 8
How much is your medicine fee 90000000
Have you undergone surgery (Yes or No)Yes
Enter your surgery fee 80000000
PS D:\Desktop\Cprogram> 

问题原因分析

  1. char变量使用%s格式符读取的内存越界问题

    • agree是单个char类型变量,仅占1字节内存,但代码中用scanf("%s", &agree);读取输入。%s用于读取字符串,会把输入的所有字符(包括后续的'e'、's'以及自动添加的字符串结束符'\0')依次写入&agree指向的内存地址。
    • 这会直接覆盖agree后面相邻的内存区域(恰好是oper变量的内存),导致oper的初始值被破坏。后续读取oper时,内存已被篡改,进而出现输入异常甚至程序崩溃。
  2. printf格式符不匹配的未定义行为

    • printf("%s", agree);中,%s要求传入字符串指针,但实际传入的是char类型的agree。程序会把agree的字符值当作内存地址去读取字符串,属于未定义行为,可能输出乱码或导致程序异常。

修复方案

修复后的代码

#include <stdio.h>

int main()
{
  int inpa, med, oper, day, total;
  char agree;
  

  printf("                     Bach Mai Hospital");
  printf("\n\nHello, please enter your fee and we will calculate\npayment based on your insurance\n");
  printf("How many days have you been in the hospital ");
  scanf("%d", &day);
  printf("How much is your medicine fee ");
  scanf("%d", &med);

  // 用%c读取单个字符,前面加空格跳过输入缓冲区的换行符
  printf("Have you undergone surgery (Yes or No)");
  scanf(" %c", &agree);
  
  switch(agree){
  case 'Y':
  case 'y': // 兼容小写输入
    printf("Enter your surgery fee ");
    scanf("%d", &oper);
    break;
  case 'N':
  case 'n': // 兼容小写输入
    oper = 0;
    break;
  default:
    printf("Invalid input, defaulting to no surgery.\n");
    oper = 0;
    break;
  };
  // 用%c打印单个字符
  printf("Your choice: %c\n", agree);

  inpa = day * 15000;
  printf("Your total fee\n");
  printf("Inpatient fee: %-10d x 15000 = %d\n", day, inpa);
  printf("Medicine fee: %-10d\n", med);
  printf("Surgery fee: %-10d\n", oper);
  total = inpa + med + oper;
  printf("\n\nYou pay: %d\n", total);

  return 0;

}

关键修复点

  • 将scanf("%s", &agree);改为scanf(" %c", &agree);:%c专门用于读取单个字符,前面的空格会自动跳过输入缓冲区中残留的换行符,避免读取到之前输入留下的空白字符。
  • 将printf("%s", agree);改为printf("%c", agree);:用%c匹配char类型变量,避免未定义行为。
  • 增加大小写兼容的判断和默认分支:处理用户输入小写字母或无效字符的情况,提升程序健壮性。

内容的提问来源于stack exchange,提问作者Phan Đào Minh Quân

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 04:35:27