C语言实现歌手比赛评分系统:结构体与文件操作实战

Leo
Leo
发布时间:2026-10-15| 6人浏览过
原创

本文展示了一个基于C语言的歌手比赛评分系统,通过结构体存储选手数据,实现从录入、10位评委打分、剔除极值求平均分、排名统计到文件保存的全流程功能。

一、 系统设计目标

本实例旨在解决简单的赛事成绩管理问题。核心需求包括:

  • 数据管理:记录选手编号、姓名等基本信息。
  • 评分算法:收集10位评委的打分,采用行业通用的“去掉一个最高分,去掉一个最低分”规则计算总分和平均分。
  • 数据处理:实现成绩的动态排序(从高到低)和按编号查询。
  • 持久化:将处理后的数据写入本地文件以备查看。

二、 界面与交互预览

系统运行后,控制台将显示主菜单供用户选择操作模式,各步骤的输入与输出界面如下所示。

系统启动后展示的基础菜单界面。

选手基本信息录入时的界面提示。

逐个输入评委打分的交互过程。

最终生成的成绩排名列表输出。

三、 核心逻辑解析

第1步:定义数据结构

为了高效管理多名选手的信息,使用 struct 定义结构体。每个结构体实例包含以下字段:

  • num: 选手编号。
  • name: 选手姓名(字符数组)。
  • score[10]: 存放10位评委的原始打分。
  • aver: 计算后的平均分。
  • sum: 原始总分(用于调试或备份)。
  • ord: 根据平均分计算出的排名。

第2步:数据录入模块

在 singer_information 函数中,程序循环接收用户输入的选手数量 b,随后逐个录入编号和姓名。此步骤仅完成基础档案建立,暂不涉及分数。

第3步:评委打分与极值剔除

这是系统的核心算法部分,分为两步逻辑:

  1. 录入打分:singer_score 函数遍历所有选手,逐个接收1-10号评委的评分,并存入 score 数组,同时累加得到原始 sum。
  2. 计算有效分:singer_grade 函数遍历每位选手的成绩数组,找出 max(最高分)和 min(最低分)。计算公式为:
    平均分 = (原始总分 - 最高分 - 最低分) / 8.0。

第4步:成绩排序与排名

order 函数通过嵌套循环比较各位选手的 aver(平均分),计算其名次 ord。最终输出时,按照排名顺序打印选手姓名、名次及得分。

第5步:数据存储

利用标准库 stdio.h 中的文件指针 FILE *fp,以追加或写入模式打开 歌手.txt 文件。遍历数组,使用 fprintf 将关键数据格式化写入磁盘,实现数据的持久化保存。

程序整体功能模块的思维导图,涵盖录入、打分、排序、查询及文件存取。

四、 C语言完整源码

以下是整合后的完整源代码。请注意,原始代码中部分 `scanf` 格式符存在不匹配风险(如 float 类型误用 %d),实际编译时建议核对参数类型以确保稳定运行。

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

/* 定义歌手结构体 */
struct singer {
    int num;
    char name[10];
    float score[20]; /* 预留空间存储评委打分 */
    float aver;
    float sum;
    int ord;
};

struct singer singers[100]; /* 最大支持100名选手 */

/* 输入选手基本信息 */
void singer_information(int b) {
    int i;
    for(i=1; i<=b; i++) {
        printf("请输入选手编号:");
        scanf("%d", &singers[i].num);
        printf("请输入选手姓名:");
        scanf("%s", singers[i].name); /* 修正:数组名无需取地址 */
    }
}

/* 输入评委打分并计算原始总分 */
int singer_score(int b) {
    int j, c;
    for(j=1; j<=b; j++) {
        for(c=1; c<=10; c++) {
            printf("请输入评委%d对歌手%s的打分: ", c, singers[j].name);
            scanf("%f", &singers[j].score[c]);
        }
        /* 初始计算原始总和 */
        singers[j].sum = 0;
        for(c=1; c<=10; c++) {
            singers[j].sum += singers[j].score[c];
        }
    }
    return 0;
}

/* 去除最高/最低分,计算平均分 */
int singer_grade(int b) {
    int a, c;
    float max, min;
    for(a=1; a<=b; a++) {
        max = singers[a].score[1];
        min = singers[a].score[1];
        
        /* 遍历找极值 */
        for(c=1; c<=10; c++) {
            if(max < singers[a].score[c]) max = singers[a].score[c];
            if(min > singers[a].score[c]) min = singers[a].score[c];
        }
        
        /* 计算平均分:(总分 - 最高 - 最低) / 8 */
        singers[a].aver = (singers[a].sum - max - min) / 8.0;
    }
    return 0;
}

/* 计算排名并输出结果 */
int order(int b) {
    int i, j, t;
    
    /* 计算每个人的名次 */
    for(i=1; i<=b; i++) {
        t = 1;
        for(j=1; j<=b; j++) {
            /* 如果他人分数高于当前人,名次后退 */
            if(singers[i].aver < singers[j].aver) {
                t++;
            }
        }
        singers[i].ord = t;
    }
    
    /* 按名次输出 */
    printf("\n--- 比赛成绩排名 ---\n");
    for(i=1; i<=b; i++) {
        for(j=1; j<=b; j++) {
            if(singers[j].ord == i) {
                printf("姓名:%s | 编号:%d | 平均分:%.2f | 排名第:%d\n",
                       singers[j].name, singers[j].num, singers[j].aver, singers[j].ord);
            }
        }
    }
    printf("----------------------\n");
    return 0;
}

/* 数据查询 */
int search(int c, int b) {
    if(c < 1 || c > b) {
        printf("无效编号!\n");
        return -1;
    }
    printf("所查选手数据:\n");
    printf("编号: %d | 姓名: %s | 平均分: %.2f | 总分: %.2f\n",
           singers[c].num, singers[c].name, singers[c].aver, singers[c].sum);
    return 0;
}

/* 主函数 */
int main() {
    int a, b, c, n=1;
    FILE *fp;
    
    /* 初始化文件 */
    fp = fopen("singer_results.txt", "w+");
    if(fp == NULL) {
        printf("文件打开失败!\n");
        return 1;
    }
    
    printf("       *** 歌手比赛评分系统 *** \n");
    while(n) {
        printf("\n*********************\n");
        printf("* 1) 录入选手数据   *\n");
        printf("* 2) 评委打分       *\n");
        printf("* 3) 成绩排名       *\n");
        printf("* 4) 数据查询       *\n");
        printf("* 5) 保存文件       *\n");
        printf("* 6) 退出系统       *\n");
        printf("*********************\n");
        printf("请选择操作: ");
        scanf("%d", &a);
        
        switch(a) {
            case 1:
                printf("请输入参赛选手人数: ");
                scanf("%d", &b);
                singer_information(b);
                break;
            case 2:
                if(b == 0) { printf("请先录入选手数据!\n"); break; }
                singer_score(b);
                break;
            case 3:
                if(b == 0) { printf("无数据!\n"); break; }
                singer_grade(b);
                order(b);
                break;
            case 4:
                if(b == 0) { printf("无数据!\n"); break; }
                printf("请输入要查询的选手编号: ");
                scanf("%d", &c);
                search(c, b);
                break;
            case 5:
                printf("正在写入文件...\n");
                rewind(fp); /* 回到文件头重写 */
                for(int i=1; i<=b; i++) {
                    fprintf(fp, "%d %s %.2f %.2f\n",
                            singers[i].num, singers[i].name, 
                            singers[i].aver, singers[i].sum);
                }
                fclose(fp);
                printf("数据已保存至 singer_results.txt\n");
                /* 重新打开以便下次写入 */
                fp = fopen("singer_results.txt", "w+");
                break;
            case 6:
                exit(0);
            default:
                printf("输入错误,请重试!\n");
        }
    }
    fclose(fp);
    return 0;
}

五、 关键点说明

  1. 数组索引:C语言数组从0开始,但本例为了贴近业务逻辑(第1位选手),在逻辑上使用1-based索引,需注意边界检查。
  2. 浮点数精度:成绩涉及小数,务必使用 float 或 double 类型,并在 scanf/printf 中使用 %f。
  3. 输入缓冲:混合使用 scanf 读取数字和字符串时,缓冲区残留的回车符可能会干扰后续 scanf("%s") 的执行,实际开发中建议在读取字符串前清空缓冲区或使用 吸收回车。
以上就是C语言实现歌手比赛评分系统的详细内容,更多关于C语言结构与函数的学习资料请关注本站其它相关文章!
相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。