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

scanf提前终止问题:汽车受欢迎度统计程序输入异常

C语言程序scanf提前终止循环及统计异常问题解决

问题背景

需要统计孟买、加尔各答、德里、马德拉斯四座城市中Ambassador、Fiat、Dolphin、Maruti四款汽车的受欢迎度,输入为城市首字母+车型编码的组合,预设循环36次接收36组数据,但程序仅接收19组输入就提前终止,且输出结果存在异常(如马德拉斯的Maruti数值与Ambassador一致)。

问题原因分析

  1. scanf读取换行符导致循环异常:
    使用scanf("%c %hu", &city, &car)时,%c会读取输入缓冲区中的任意字符,包括每次输入后按下的换行符\n。每输入一组有效数据后,换行符会留在缓冲区,下一次循环中%c会直接读取这个换行符,此时scanf尝试读取车型编码%hu时,会遇到下一组输入的城市首字母(非数字),导致转换失败,循环计数被消耗但未完成有效数据录入。多次循环后,36次循环会被无效的换行符快速消耗,提前终止。

  2. 输出笔误导致统计结果异常:
    马德拉斯的Maruti输出语句中,错误使用了survey[4][1](对应Ambassador的统计值),正确应为survey[4][4]。

  3. 非标准main函数定义:
    C标准中main函数应返回int类型,而非void,这可能导致程序行为不可预测。

修复方案

  1. 修改scanf格式串,在%c前添加空格,跳过所有空白字符(换行、空格、制表符),确保每次读取的都是有效城市首字母:
    scanf(" %c %hu", &city, &car);
    
  2. 修正马德拉斯输出的笔误:
    将survey[4][1]改为survey[4][4]。
  3. 将void main()改为int main(),并在末尾添加return 0;,符合C标准。
  4. (可选)检查scanf的返回值,确保每次成功读取2个数据,避免无效输入干扰统计:
    if (scanf(" %c %hu", &city, &car) != 2) {
        printf("输入无效,请重新输入\n");
        i--; // 回退循环计数,重新接收该组输入
        continue;
    }
    

修复后的完整代码

#include<stdio.h>

int main(){
    unsigned short car, i, survey[5][5] = {{0}}; // 简化初始化方式
    char city;
    printf("Enter city initial and car code\n");
    for (i = 0; i < 36; i++)
    {
        // 检查输入是否有效
        if (scanf(" %c %hu", &city, &car) != 2) {
            printf("无效输入,请重新输入\n");
            i--;
            // 清空输入缓冲区的无效内容
            while (getchar() != '\n');
            continue;
        }
        switch (city)
        {
        case 'b':
            survey[1][car]++;
            break;
        case 'c':
            survey[2][car]++;
            break;
        case 'd':
            survey[3][car]++;
            break;
        case 'm': // 显式处理马德拉斯的情况,避免default覆盖其他无效输入
            survey[4][car]++;
            break;
        default:
            printf("无效城市首字母,请输入b/c/d/m\n");
            i--;
            continue;
        }
    }
    printf("BOMBAY:\nAmbassador = %hu\nFiat = %hu\nDolphin = %hu\nMaruti = %hu\n",
           survey[1][1], survey[1][2], survey[1][3], survey[1][4]);
    printf("CALCUTTA:\nAmbassador = %hu\nFiat = %hu\nDolphin = %hu\nMaruti = %hu\n",
           survey[2][1], survey[2][2], survey[2][3], survey[2][4]);
    printf("DELHI:\nAmbassador = %hu\nFiat = %hu\nDolphin = %hu\nMaruti = %hu\n",
           survey[3][1], survey[3][2], survey[3][3], survey[3][4]);
    printf("MADRAS:\nAmbassador = %hu\nFiat = %hu\nDolphin = %hu\nMaruti = %hu\n",
           survey[4][1], survey[4][2], survey[4][3], survey[4][4]); // 修正笔误
    return 0;
}

修复效果说明

  • 修改后的scanf会自动跳过换行符,确保每次循环都接收一组有效输入,36次循环可完整接收36组数据。
  • 修正输出笔误后,马德拉斯的Maruti统计值将正确显示。
  • 添加输入有效性检查后,可避免无效输入导致的统计错误,提升程序健壮性。

内容的提问来源于stack exchange,提问作者Anuska Saha

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 13:53:22