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

C语言棒球选手打击率计算程序故障排查与修正需求

修正棒球选手打击率计算程序的三类错误

需求:编写C语言程序计算100名棒球选手的打击率,输入选手姓名(Name)、打数(at_bats)、安打数(hits)。当打击率≥0.50时备注为"High",否则为"Low",输出为表格形式,打击率公式:Batting Ave = Hits/At_bats。

当前代码设定MAX=2,运行出现三类问题:

  1. 跨平台清屏命令system("cls")报错
  2. 第二名选手姓名重复显示为第一名的姓名
  3. 打击率计算结果均为0.000000,备注全部显示为Low

错误排查与修复方案

1. 跨平台清屏命令问题

system("cls")仅在Windows系统有效,Linux/macOS下会执行失败。解决方案是通过预编译指令判断操作系统,选择对应清屏命令:

  • Windows环境:使用system("cls")
  • Linux/macOS环境:使用system("clear")
    同时需要包含<stdlib.h>头文件以调用system()函数。

2. 姓名重复显示问题

这类问题通常是因为所有选手的姓名字段复用了同一内存空间(比如使用未分配独立内存的char *name指针),后续输入会覆盖之前的内容。修复方法是在结构体中为每个选手定义固定长度的字符数组(如char name[50];),确保每个姓名都有独立存储区域。

3. 打击率计算为0的问题

这是整数除法特性导致的:如果hits和at_bats都是整数类型,hits/at_bats会执行整数除法(结果取整),当hits < at_bats时结果直接为0。修复方法是将其中一个操作数强制转换为浮点型,比如(float)hits / at_bats,触发浮点除法得到精确的小数结果。

完整修正代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX 2  // 测试用,实际需求可修改为100

typedef struct {
    char name[50];  // 为每个选手分配独立的姓名存储空间
    int at_bats;
    int hits;
    float batting_avg;
    char remark[10];
} Player;

// 跨平台清屏函数
void clear_screen() {
    #ifdef _WIN32
        system("cls");
    #else
        system("clear");
    #endif
}

int main() {
    Player players[MAX];
    int i;

    clear_screen();

    // 输入选手信息
    for (i = 0; i < MAX; i++) {
        printf("请输入第%d名选手信息:\n", i+1);
        printf("姓名: ");
        fflush(stdin);  // 清除输入缓冲区残留的换行符
        fgets(players[i].name, sizeof(players[i].name), stdin);
        // 去除fgets读取的末尾换行符
        players[i].name[strcspn(players[i].name, "\n")] = '\0';

        printf("打数: ");
        scanf("%d", &players[i].at_bats);
        // 合法性检查:打数不能为0或负数
        while (players[i].at_bats <= 0) {
            printf("打数不能为0或负数,请重新输入: ");
            scanf("%d", &players[i].at_bats);
        }

        printf("安打数: ");
        scanf("%d", &players[i].hits);
        // 合法性检查:安打数不能为负,且不能超过打数
        while (players[i].hits < 0 || players[i].hits > players[i].at_bats) {
            printf("安打数必须在0到打数之间,请重新输入: ");
            scanf("%d", &players[i].hits);
        }

        // 计算打击率:强制转换为浮点型避免整数除法
        players[i].batting_avg = (float)players[i].hits / players[i].at_bats;
        // 设置备注
        strcpy(players[i].remark, players[i].batting_avg >= 0.5 ? "High" : "Low");

        clear_screen();
    }

    // 输出表格形式的结果
    printf("=============================================\n");
    printf("序号\t姓名\t\t打数\t安打数\t打击率\t\t备注\n");
    printf("=============================================\n");
    for (i = 0; i < MAX; i++) {
        printf("%d\t%s\t\t%d\t%d\t%.4f\t\t%s\n", 
               i+1, 
               players[i].name, 
               players[i].at_bats, 
               players[i].hits, 
               players[i].batting_avg, 
               players[i].remark);
    }
    printf("=============================================\n");

    return 0;
}

代码关键优化点

  • 结构体中使用固定长度字符数组存储姓名,彻底避免内存复用导致的姓名覆盖问题
  • 新增clear_screen()函数,通过预编译指令实现跨平台兼容的清屏操作
  • 计算打击率时强制将hits转换为float,确保执行浮点除法得到精确结果
  • 添加输入合法性校验,防止打数为0(除零错误)、安打数超出合理范围的情况
  • 使用fgets()读取姓名,避免scanf()读取字符串时的缓冲区溢出问题,同时处理掉换行符保证输出格式整洁

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 16:05:38