需求描述
对一个有N个学生的班级,每个学生有 M门课程。该系统实现对班级成绩的录入、显示
修改、排序、保存等操作的管理。(用文件保存)
功能要求:
(1)本系统采用一个结构体数组,每个数据的结构应当包括:学号、姓名、M门课程名称,
(2)本系统显示这样的菜单:
请选择系统功能项:
a、成绩录入
b、成绩显示
c、成绩保存
d、成绩排序
e、成绩修改
f、成绩统计
1)显示每门课程成绩最高的学生的基本信息
2)显示每门课程的平均成绩
3)显示超过某门课程平均成绩的学生人数
g、退出系统
(3)执行一个具体的功能之后,程序将重新显示菜单,
(4)将学生成绩保存到文件中。
代码
#include <stdio.h>
#include <string.h>
// 阅读代码思路
// 1、先看Student结构体,有什么内容
// 2、翻到最下面的main函数开始看
// main函数主要逻辑,定义几个变量(1)记录用户的选择choice,
// (2)当前系统里面保存了多少个学生信息numStudents
// (3)当前系统最多容纳多少个学生maxStudents;
// (4)保存当前系统的学生信息数组students
// 然后就是loadGrades,从文件中加载学生信息到students数组。并且设置numStudents。
// 这个操作就是系统开始运行的时候先读取历史数据进行初始化。
// 然后就是while循环。
// 展示菜单->等待用户输入->判断用户输入->调用对应函数->结束->展示菜单->等待用户输入...
// 3、while循环中,每个功能对应一个函数,可以一个个函数去理解。然后就能掌握整个程序到底是什么意思
// 4、排序可能很难理解,可以忽略,只要知道他是排序就可以了
// 定义学生结构体
struct Student {
char name[50]; // 姓名
int studentID; // 学号
float grades[4]; // 每门课程的成绩:高等数学 Java C语言 大学英语
};
// 加载数据的函数
int loadGrades(struct Student students[], int numStudents) {
// 以只读的方式打开文件
FILE *file = fopen("data.txt", "r");
// NULL代表打开文件失败,数据文件不存在,那么要新创建一个
if (file == NULL) {
// 如果文件不存在,创建一个新文件,w代表写,文件不存在会自动创建一个文件
file = fopen("data.txt", "w");
fclose(file); // 创建文件后立即关闭,不然别的地方要打开打开不了
printf("已创建新文件 data.txt\n");
} else {
// 文件存在就从文件里面读取数据,feof就是判断当前有没有读到文件尾部,没有就一直读
while (!feof(file)) {
fscanf(file, "%s", students[numStudents].name);
fscanf(file, "%d", &students[numStudents].studentID);
for (int j = 0; j < 4; j++) {
fscanf(file, "%f", &students[numStudents].grades[j]);
}
// 无效数据跳过
if (students[numStudents].studentID==0){
continue;
}
(numStudents)++; // 增加学生数量
}
// 读完要关闭文件
fclose(file);
printf("已从 data.txt 文件加载数据\n");
}
return numStudents;
}
// 录入成绩的函数
int enterGrades(struct Student students[], int numStudents, int maxStudents) {
if (numStudents < maxStudents) {
// 录入学生信息和成绩
printf("\n学生 #%d\n", numStudents + 1);
printf("姓名: ");
scanf("%s", students[numStudents].name);
printf("学号: ");
scanf("%d", &students[numStudents].studentID);
printf("请输入高等数学成绩: ");
scanf("%f", &students[numStudents].grades[0]);
printf("请输入Java成绩: ");
scanf("%f", &students[numStudents].grades[1]);
printf("请输入C语言成绩: ");
scanf("%f", &students[numStudents].grades[2]);
printf("请输入大学英语成绩: ");
scanf("%f", &students[numStudents].grades[3]);
(numStudents)++; // 增加学生数量
} else {
printf("已达到最大学生容量,无法继续录入学生信息。\n");
}
return numStudents;
}
// 显示成绩的函数
void displayGrades(struct Student students[], int numStudents) {
// 显示学生信息和成绩
// \n代表换行,\t代表大空格
printf("\n学生成绩单:\n");
for (int i = 0; i < numStudents; i++) {
printf("学生 #%d\t", i + 1);
printf("姓名: %s\t", students[i].name);
printf("学号: %d\t", students[i].studentID);
printf("高等数学:");
printf("成绩 %.2f\t", students[i].grades[0]);
printf("Java:");
printf("成绩 %.2f\t", students[i].grades[1]);
printf("C语言:");
printf("成绩 %.2f\t", students[i].grades[2]);
printf("大学英语:");
printf("成绩 %.2f\t", students[i].grades[3]);
printf("\n");
}
}
// 保存成绩到文件的函数
void saveGrades(struct Student students[], int numStudents) {
// 写的方式打开文件,向里面写数据
FILE *file = fopen("data.txt", "w");
if (file == NULL) {
printf("无法打开文件 data.txt\n");
return;
}
for (int i = 0; i < numStudents; i++) {
fprintf(file, "%s ", students[i].name);
fprintf(file, "%d ", students[i].studentID);
fprintf(file, "%.2f ", students[i].grades[0]);
fprintf(file, "%.2f ", students[i].grades[1]);
fprintf(file, "%.2f ", students[i].grades[2]);
fprintf(file, "%.2f ", students[i].grades[3]);
// 保存完一个学生的信息之后,换行(每一行一个学生)
fprintf(file,"\n");
}
fclose(file);
printf("成绩已保存到 data.txt 文件\n");
}
// 成绩排序的函数
void sortGrades(struct Student students[], int numStudents) {
if (numStudents > 0) {
// 排序
for (int i = 0; i < numStudents - 1; i++) {
for (int j = 0; j < numStudents - i - 1; j++) {
float avgA = 0, avgB = 0;
// 计算学生A平均分
for (int k = 0; k <4; k++) {
avgA += students[j].grades[k];
}
avgA /= 4;
// 计算学生B平均分
for (int k = 0; k < 4; k++) {
avgB += students[j + 1].grades[k];
}
avgB /= 4;
// 比较两个学生的平均分
if (avgA < avgB) {
struct Student temp = students[j];
students[j] = students[j + 1];
students[j + 1] = temp;
}
}
}
printf("成绩已按平均分排序\n");
} else {
printf("没有学生数据可排序\n");
}
}
// 修改成绩的函数
void modifyGrades(struct Student students[], int numStudents) {
if (numStudents == 0) {
printf("没有学生数据可供修改\n");
return;
}
int studentID;
printf("请输入要修改成绩的学生学号: ");
scanf("%d", &studentID);
// 记录根据学号找到的学生个数
int found = 0;
// for循环找学生
for (int i = 0; i < numStudents; i++) {
if (students[i].studentID == studentID) {
printf("找到学生 #%d,学生信息如下:\n", i + 1);
printf("姓名: %s\t", students[i].name);
printf("学号: %d\t", students[i].studentID);
printf("高等数学:");
printf("成绩 %.2f\t", students[i].grades[0]);
printf("Java:");
printf("成绩 %.2f\t", students[i].grades[1]);
printf("C语言:");
printf("成绩 %.2f\t", students[i].grades[2]);
printf("大学英语:");
printf("成绩 %.2f\t", students[i].grades[3]);
printf("\n");
printf("输入要修改的课程编号 (1 到 4): ");
int courseIndex;
scanf("%d", &courseIndex);
if (courseIndex >= 1 && courseIndex <= 4) {
printf("输入新的成绩: ");
scanf("%f", &students[i].grades[courseIndex - 1]);
printf("成绩已更新\n");
// 代表找到了学生
found = 1;
break;
} else {
printf("无效的课程编号\n");
break;
}
}
}
// 根据学号没找到学生
if (!found) {
printf("未找到该学生的记录\n");
}
}
// 成绩统计的函数
void gradeStatistics(struct Student students[], int numStudents) {
// 记录用户的输入,因为等等会有子菜单要用户选择,用户选择的结果保存在choice
int choice;
if (numStudents == 0) {
printf("没有学生数据可供统计\n");
return;
}
printf("\n成绩统计菜单:\n");
printf("1. 每门课程成绩最高的学生\n");
printf("2. 每门课程的平均成绩\n");
printf("3. 超过某门课程平均成绩的学生人数\n");
printf("请选择操作: ");
scanf(" %d", &choice);
// 根据用户的学生,跳到不同的case执行代码
switch (choice) {
case 1:
// 每门课程成绩最高的学生
for (int courseIndex = 0; courseIndex <4; courseIndex++) {
float maxGrade = 0;
int maxStudentIndex = -1;
for (int i = 0; i < numStudents; i++) {
if (students[i].grades[courseIndex] > maxGrade) {
maxGrade = students[i].grades[courseIndex];
maxStudentIndex = i;
}
}
if (courseIndex==0){
printf("高等数学最高分学生: %s, 成绩: %.2f\n",
students[maxStudentIndex].name, maxGrade);
}
if (courseIndex==1){
printf("Java最高分学生: %s, 成绩: %.2f\n",
students[maxStudentIndex].name, maxGrade);
}
if (courseIndex==2){
printf("C语言最高分学生: %s, 成绩: %.2f\n",
students[maxStudentIndex].name, maxGrade);
}
if (courseIndex==3){
printf("大学英语最高分学生: %s, 成绩: %.2f\n",
students[maxStudentIndex].name, maxGrade);
}
}
break;
case 2:
// 每门课程的平均成绩
for (int courseIndex = 0; courseIndex < 4; courseIndex++) {
float totalGrade = 0;
int numStudentsInCourse = 0;
for (int i = 0; i < numStudents; i++) {
totalGrade += students[i].grades[courseIndex];
numStudentsInCourse++;
}
float averageGrade = totalGrade / numStudentsInCourse;
if (courseIndex==0){
printf("高等数学平均分%.2f\n",
averageGrade);
}
if (courseIndex==1){
printf("Java均分%.2f\n",
averageGrade);
}
if (courseIndex==2){
printf("C语言平均分%.2f\n",
averageGrade);
}
if (courseIndex==3){
printf("大学英语平均分%.2f\n",
averageGrade);
}
}
break;
case 3: {
int courseIndex;
printf("请输入要查询的课程索引 (0: 高等数学, 1: Java, 2: C语言, 3: 大学英语): ");
scanf("%d", &courseIndex);
if (courseIndex < 0 || courseIndex > 3) {
printf("无效的课程索引\n");
return;
}
float totalGrade = 0;
int numStudentsInCourse = 0;
// 计算选定课程的平均成绩
for (int i = 0; i < numStudents; i++) {
totalGrade += students[i].grades[courseIndex];
numStudentsInCourse++;
}
float averageGrade = totalGrade / numStudentsInCourse;
// 统计超过平均成绩的学生人数
int aboveAverageCount = 0;
for (int i = 0; i < numStudents; i++) {
if (students[i].grades[courseIndex] > averageGrade) {
aboveAverageCount++;
}
}
if (courseIndex == 0) {
printf("高等数学成绩超过平均分的学生人数: %d\n", aboveAverageCount);
} else if (courseIndex == 1) {
printf("Java成绩超过平均分的学生人数: %d\n", aboveAverageCount);
} else if (courseIndex == 2) {
printf("C语言成绩超过平均分的学生人数: %d\n", aboveAverageCount);
} else if (courseIndex == 3) {
printf("大学英语成绩超过平均分的学生人数: %d\n", aboveAverageCount);
}
break;
}
default:
printf("无效选项,请重新选择\n");
break;
}
}
int main() {
char choice;
int numStudents = 0; // 当前学生数量,初始为0
int maxStudents = 100; // 最大容纳学生数量
// 声明一个学生数组
struct Student students[maxStudents];
// 从文件加载数据
numStudents=loadGrades(students, numStudents);
while (1) {
printf("\n学生成绩管理系统菜单:\n");
printf("a. 成绩录入\n");
printf("b. 成绩显示\n");
printf("c. 成绩保存\n");
printf("d. 成绩排序\n");
printf("e. 成绩修改\n");
printf("f. 成绩统计\n");
printf("g. 退出\n");
printf("请选择操作: ");
scanf(" %c", &choice); // 注意空格,以防止换行字符的干扰
switch (choice) {
case 'a':
numStudents=enterGrades(students, numStudents, maxStudents);
break;
case 'b':
displayGrades(students, numStudents);
break;
case 'c':
saveGrades(students, numStudents);
break;
case 'd':
sortGrades(students, numStudents);
break;
case 'e':
modifyGrades(students, numStudents);
break;
case 'f':
gradeStatistics(students,numStudents);
break;
case 'g':
printf("退出程序\n");
return 0;
default:
printf("无效选项,请重新选择\n");
break;
}
}
return 0;
}
演示
结尾
如有需帮助,请私信我