项目描述
设计一款用于课程任务检查或比赛计分的软件,基本功能:
(1)设置本课程的学生总数
(2)根据本次参与的学生总数,随机抽取一个还未汇报演讲的学生的学号。
(3)每个学生汇报演讲完毕,输入该学生的得分(假设有5个评委,则需输入5个成绩)。
(4)计算该选手的得分:去掉最高分和最低分,其余的分数求平均,并显示选手序号、姓名、得分。
(5)输出参加比赛过的所有学生的成绩及当前排名。
(6)对演讲过的学生作上标记,下次程序运行时不再抽取该学号。
(7)每次退出程序时(不一定一次能进行完所有的学生的汇报,可以分多次进行),将学生的序号、姓名、成绩写入文件。
(8)结束对学生成绩进行排序,显示,并按照一等奖10%、二等奖20%、三等奖30%的比例确定选手的获奖名次,并将结果写入文件保存。
拓展功能:赛前事先输入评委人数,设置选手姓名、序号,选手上场顺序由程序随机抽取,已经抽取过的选手信息在文件中做出标记,下次不再抽取。其他更多方便用户使用的功能。
实现代码
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#define MAX_STUDENTS 100 // 最大学生数
#define MAX_NAME_LEN 20 // 最大姓名长度
#define MAX_SCORES 5 // 每个学生的成绩数
#define FILE_NAME "scores.txt" // 存储成绩的文件名
// 学生结构体
struct student {
char name[MAX_NAME_LEN];
float scores[MAX_SCORES];
int reported; // 是否已汇报演讲
};
// 抽取未汇报演讲的学生的序号
int draw_student(struct student students[], int total_students) {
int i, index;
do {
index = rand() % total_students;
} while (students[index].reported);
return index;
}
// 输入一个学生的成绩
void input_scores(struct student *s) {
int i;
printf("请输入 %s 的成绩:\n", s->name);
for (i = 0; i < MAX_SCORES; i++) {
scanf("%f", &s->scores[i]);
}
}
// 计算一个学生的得分
float calculate_score(struct student *s) {
int i;
float sum = 0, max = 0, min = 100;
for (i = 0; i < MAX_SCORES; i++) {
if (s->scores[i] > max) { max = s->scores[i]; }
if (s->scores[i] < min) { min = s->scores[i]; }
sum += s->scores[i];
}
return (sum - max - min) / (MAX_SCORES - 2);
}
// 输出参加比赛的所有学生的成绩及当前排名
void output_scores(struct student students[], int total_students) {
int i, j;
float scores[MAX_STUDENTS];
char names[MAX_STUDENTS][MAX_NAME_LEN];
for (i = 0; i < total_students; i++) {
scores[i] = calculate_score(&students[i]);
strcpy(names[i], students[i].name);
}
// 冒泡排序
for (i = 0; i < total_students - 1; i++) {
for (j = 0; j < total_students - 1 - i; j++) {
if (scores[j] < scores[j+1]) {
float temp_score = scores[j];
scores[j] = scores[j+1];
scores[j+1] = temp_score;
char temp_name[MAX_NAME_LEN];
strcpy(temp_name, names[j]);
strcpy(names[j], names[j+1]);
strcpy(names[j+1], temp_name);
}
}
}
printf("成绩单:\n");
for (i = 0; i < total_students; i++) {
printf("%d. %s:%.2f\n", i+1, names[i], scores[i]);
}
}
// 写入成绩文件
void write_scores(struct student students[], int total_students) {
int i;
FILE *fp = fopen(FILE_NAME, "w");
if (!fp) {
printf("无法打开文件 %s\n", FILE_NAME);
return;
}
for (i = 0; i < total_students; i++) {
fprintf(fp, "%s ", students[i].name);
int j;
for (j = 0; j < MAX_SCORES; j++) {
fprintf(fp, "%.2f ", students[i].scores[j]);
}
fprintf(fp, "\n");
}
fclose(fp);
}
// 读取成绩文件
void read_scores(struct student students[], int total_students) {
int i;
FILE *fp = fopen(FILE_NAME, "r");
if (!fp) { return; }
while (!feof(fp)) {
char name[MAX_NAME_LEN];
fscanf(fp, "%s", name);
for (i = 0; i < total_students; i++) {
if (strcmp(students[i].name, name) == 0) {
int j;
for (j = 0; j < MAX_SCORES; j++) {
fscanf(fp, "%f", &students[i].scores[j]);
}
students[i].reported = 1;
break;
}
}
}
fclose(fp);
}
int main() {
srand(time(NULL)); // 设置随机种子
struct student students[MAX_STUDENTS];
int total_students, i;
printf("请输入学生总数:");
scanf("%d", &total_students);
if (total_students > MAX_STUDENTS) {
printf("学生总数不能超过 %d\n", MAX_STUDENTS);
return 0;
}
for (i = 0; i < total_students; i++) {
printf("请输入第 %d 个学生的姓名:", i+1);
scanf("%s", students[i].name);
students[i].reported = 0;
}
read_scores(students, total_students);
while (1) {
int index = draw_student(students, total_students);
printf("下一个汇报演讲的学生是:%s\n", students[index].name);
input_scores(&students[index]);
float score = calculate_score(&students[index]);
printf("%s 的得分是:%.2f\n", students[index].name, score);
write_scores(students, total_students);
output_scores(students, total_students);
students[index].reported = 1;
int finished = 1;
for (i = 0; i < total_students; i++) {
if (!students[i].reported) { finished = 0; }
}
if (finished) { break; }
}
output_scores(students, total_students);
return 0;
}
此代码实现了基本功能,包括随机抽号、输入成绩、计算得分、输出排名等功能,并支持将成绩写入文件和从文件中读取成绩。对于拓展功能,可以根据需要进行修改和扩展。
效果截图
© 版权声明
本站资源来自互联网收集,仅供用于学习和交流,请勿用于商业用途。如有侵权、不妥之处,请联系站长并出示版权证明以便删除。敬请谅解!
THE END