#include
#include
#include
#include
#include
#define MAX_STUDENTS 1000
#define MAX_NAME_LEN 50
#define MAX_ID_LEN 20
#define MAX_SUBJECTS 10
#define FILE_NAME "student_data.dat"
// 定义学生结构体
typedef struct {
char id[MAX_ID_LEN]; // 学号
char name[MAX_NAME_LEN]; // 姓名
char gender; // 性别 ('M'/'F')
int age; // 年龄
char className[MAX_NAME_LEN]; // 班级 (改名为 className)
float scores[MAX_SUBJECTS]; // 各科成绩
float average; // 平均分
float total; // 总分
int rank; // 排名
} Student;
// 定义全局变量
Student students[MAX_STUDENTS]; // 学生数组
int studentCount = 0; // 当前学生数量
char subjectNames[MAX_SUBJECTS][MAX_NAME_LEN] = {"语文", "数学", "英语", "物理", "化学"}; // 科目名称
int subjectCount = 5; // 科目数量
// 函数声明
void showMenu();
void addStudent();
void deleteStudent();
void modifyStudent();
void queryStudent();
void inputScores();
void calculateStatistics();
void sortStudents();
void displayAllStudents();
void saveToFile();
void loadFromFile();
void generateReport();
void displayHistogram();
int validateInput(char* str, int type);
void clearInputBuffer();
float calculateAverage(float* scores);
void swap(Student* a, Student* b);
void quickSort(Student* arr, int low, int high);
int partition(Student* arr, int low, int high);
void displayHeader();
void displayStudent(Student* student);
void searchByName();
void searchById();
void modifyScores();
void modifyInfo();
void generateClassReport();
void generateSubjectReport();
void backupData();
void restoreData();
void exportToCsv();
// 主函数
int main() {
int choice;
loadFromFile(); // 启动时加载数据
while (1) {
showMenu();
printf("\n请输入您的选择 (1-12): ");
if (scanf("%d", &choice) != 1) {
printf("输入无效,请重试!\n");
clearInputBuffer();
continue;
}
clearInputBuffer();
switch (choice) {
case 1:
addStudent();
break;
case 2:
deleteStudent();
break;
case 3:
modifyStudent();
break;
case 4:
queryStudent();
break;
case 5:
inputScores();
break;
case 6:
calculateStatistics();
break;
case 7:
sortStudents();
break;
case 8:
displayAllStudents();
break;
case 9:
generateReport();
break;
case 10:
saveToFile();
break;
case 11:
displayHistogram();
break;
case 12:
saveToFile();
printf("\n感谢使用学生成绩管理系统!再见!\n");
return 0;
default:
printf("\n无效的选择,请重试!\n");
}
}
}
// 显示主菜单
void showMenu() {
printf("\n=== 学生成绩管理系统 ===\n");
printf("1. 添加学生信息\n");
printf("2. 删除学生信息\n");
printf("3. 修改学生信息\n");
printf("4. 查询学生信息\n");
printf("5. 录入学生成绩\n");
printf("6. 统计分析成绩\n");
printf("7. 成绩排序\n");
printf("8. 显示所有学生\n");
printf("9. 生成成绩报告\n");
printf("10. 保存数据\n");
printf("11. 成绩分布图\n");
printf("12. 退出系统\n");
}
// 添加学生信息
void addStudent() {
if (studentCount >= MAX_STUDENTS) {
printf("\n错误:学生数量已达到最大限制!\n");
return;
}
Student newStudent;
printf("\n=== 添加新学生 ===\n");
// 输入学号
do {
printf("请输入学号: ");
scanf("%s", newStudent.id);
clearInputBuffer();
// 检查学号是否已存在
for (int i = 0; i < studentCount; i++) {
if (strcmp(students[i].id, newStudent.id) == 0) {
printf("错误:该学号已存在!\n");
return;
}
}
} while (!validateInput(newStudent.id, 1));
// 输入姓名
do {
printf("请输入姓名: ");
scanf("%s", newStudent.name);
clearInputBuffer();
} while (!validateInput(newStudent.name, 2));
// 输入性别
do {
printf("请输入性别 (M/F): ");
scanf("%c", &newStudent.gender);
clearInputBuffer();
newStudent.gender = toupper(newStudent.gender);
} while (newStudent.gender != 'M' && newStudent.gender != 'F');
// 输入年龄
do {
printf("请输入年龄 (15-30): ");
scanf("%d", &newStudent.age);
clearInputBuffer();
} while (newStudent.age < 15 || newStudent.age > 30);
// 输入班级
printf("请输入班级: ");
scanf("%s", newStudent.className);
clearInputBuffer();
// 初始化成绩
for (int i = 0; i < subjectCount; i++) {
newStudent.scores[i] = -1; // -1 表示未录入
}
newStudent.average = 0;
newStudent.total = 0;
newStudent.rank = 0;
// 添加到数组
students[studentCount++] = newStudent;
printf("\n学生信息添加成功!\n");
saveToFile(); // 自动保存
}
// 删除学生信息
void deleteStudent() {
char id[MAX_ID_LEN];
int found = 0;
printf("\n=== 删除学生信息 ===\n");
printf("请输入要删除的学生学号: ");
scanf("%s", id);
clearInputBuffer();
for (int i = 0; i < studentCount; i++) {
if (strcmp(students[i].id, id) == 0) {
// 显示学生信息确认
printf("\n找到学生信息:\n");
displayHeader();
displayStudent(&students[i]);
char confirm;
printf("\n确认删除该学生信息?(Y/N): ");
scanf("%c", &confirm);
clearInputBuffer();
if (toupper(confirm) == 'Y') {
// 移动后面的元素
for (int j = i; j < studentCount - 1; j++) {
students[j] = students[j + 1];
}
studentCount--;
printf("\n学生信息删除成功!\n");
saveToFile(); // 自动保存
} else {
printf("\n取消删除操作。\n");
}
found = 1;
break;
}
}
if (!found) {
printf("\n错误:未找到该学号的学生!\n");
}
}
// 修改学生信息
void modifyStudent() {
printf("\n=== 修改学生信息 ===\n");
printf("1. 修改基本信息\n");
printf("2. 修改成绩信息\n");
printf("请选择修改类型 (1-2): ");
int choice;
scanf("%d", &choice);
clearInputBuffer();
switch (choice) {
case 1:
modifyInfo();
break;
case 2:
modifyScores();
break;
default:
printf("\n无效的选择!\n");
}
}
// 修改基本信息
void modifyInfo() {
char id[MAX_ID_LEN];
int found = 0;
printf("\n请输入要修改的学生学号: ");
scanf("%s", id);
clearInputBuffer();
for (int i = 0; i < studentCount; i++) {
if (strcmp(students[i].id, id) == 0) {
printf("\n当前学生信息:\n");
displayHeader();
displayStudent(&students[i]);
// 修改信息
printf("\n请输入新的信息(直接回车保持不变):\n");
// 修改姓名
printf("姓名 [%s]: ", students[i].name);
char input[MAX_NAME_LEN];
fgets(input, MAX_NAME_LEN, stdin);
input[strcspn(input, "\n")] = 0;
if (strlen(input) > 0) {
strcpy(students[i].name, input);
}
// 修改性别
printf("性别 (M/F) [%c]: ", students[i].gender);
char gender;
scanf("%c", &gender);
clearInputBuffer();
if (toupper(gender) == 'M' || toupper(gender) == 'F') {
students[i].gender = toupper(gender);
}
// 修改年龄
printf("年龄 [%d]: ", students[i].age);
int age;
if (scanf("%d", &age) == 1) {
if (age >= 15 && age <= 30) {
students[i].age = age;
}
}
clearInputBuffer();
// 修改班级
printf("班级 [%s]: ", students[i].className);
fgets(input, MAX_NAME_LEN, stdin);
input[strcspn(input, "\n")] = 0;
if (strlen(input) > 0) {
strcpy(students[i].className, input);
}
printf("\n学生信息修改成功!\n");
saveToFile(); // 自动保存
found = 1;
break;
}
}
if (!found) {
printf("\n错误:未找到该学号的学生!\n");
}
}
// 修改成绩信息
void modifyScores() {
char id[MAX_ID_LEN];
int found = 0;
printf("\n请输入要修改成绩的学生学号: ");
scanf("%s", id);
clearInputBuffer();
for (int i = 0; i < studentCount; i++) {
if (strcmp(students[i].id, id) == 0) {
printf("\n当前学生成绩:\n");
displayHeader();
displayStudent(&students[i]);
printf("\n请输入新的成绩(-1表示保持不变):\n");
float newScore;
for (int j = 0; j < subjectCount; j++) {
printf("%s [%.1f]: ", subjectNames[j], students[i].scores[j]);
if (scanf("%f", &newScore) == 1) {
if (newScore >= 0 && newScore <= 100) {
students[i].scores[j] = newScore;
}
}
clearInputBuffer();
}
// 重新计算平均分和总分
students[i].total = 0;
int validScores = 0;
for (int j = 0; j < subjectCount; j++) {
if (students[i].scores[j] >= 0) {
students[i].total += students[i].scores[j];
validScores++;
}
}
if (validScores > 0) {
students[i].average = students[i].total / validScores;
}
printf("\n成绩修改成功!\n");
saveToFile(); // 自动保存
found = 1;
break;
}
}
if (!found) {
printf("\n错误:未找到该学号的学生!\n");
}
}
// 查询学生信息
void queryStudent() {
printf("\n=== 查询学生信息 ===\n");
printf("1. 按姓名查询\n");
printf("2. 按学号查询\n");
printf("请选择查询方式 (1-2): ");
int choice;
scanf("%d", &choice);
clearInputBuffer();
switch (choice) {
case 1:
searchByName();
break;
case 2:
searchById();
break;
default:
printf("\n无效的选择!\n");
}
}
// 按姓名查询
void searchByName() {
char name[MAX_NAME_LEN];
int found = 0;
printf("\n请输入要查询的学生姓名: ");
scanf("%s", name);
clearInputBuffer();
printf("\n查询结果:\n");
displayHeader();
for (int i = 0; i < studentCount; i++) {
if (strstr(students[i].name, name) != NULL) {
displayStudent(&students[i]);
found = 1;
}
}
if (!found) {
printf("\n未找到匹配的学生信息!\n");
}
}
// 按学号查询
void searchById() {
char id[MAX_ID_LEN];
int found = 0;
printf("\n请输入要查询的学生学号: ");
scanf("%s", id);
clearInputBuffer();
for (int i = 0; i < studentCount; i++) {
if (strcmp(students[i].id, id) == 0) {
printf("\n查询结果:\n");
displayHeader();
displayStudent(&students[i]);
found = 1;
break;
}
}
if (!found) {
printf("\n未找到该学号的学生!\n");
}
}
// 录入成绩
void inputScores() {
char id[MAX_ID_LEN];
int found = 0;
printf("\n=== 录入学生成绩 ===\n");
printf("请输入要录入成绩的学生学号: ");
scanf("%s", id);
clearInputBuffer();
for (int i = 0; i < studentCount; i++) {
if (strcmp(students[i].id, id) == 0) {
printf("\n当前学生信息:\n");
displayHeader();
displayStudent(&students[i]);
printf("\n请输入各科成绩(0-100):\n");
students[i].total = 0;
for (int j = 0; j < subjectCount; j++) {
do {
printf("%s: ", subjectNames[j]);
scanf("%f", &students[i].scores[j]);
clearInputBuffer();
if (students[i].scores[j] < 0 || students[i].scores[j] > 100) {
printf("成绩必须??0-100之间,请重新输入!\n");
}
} while (students[i].scores[j] < 0 || students[i].scores[j] > 100);
students[i].total += students[i].scores[j];
}
students[i].average = students[i].total / subjectCount;
printf("\n成绩录入成功!\n");
saveToFile(); // 自动保存
found = 1;
break;
}
}
if (!found) {
printf("\n错误:未找到该学号的学生!\n");
}
}
// 统计分析成绩
void calculateStatistics() {
printf("\n=== 成绩统计分析 ===\n");
// 各科统计数据
for (int i = 0; i < subjectCount; i++) {
float max = -1, min = 101, sum = 0, avg;
int count = 0;
int distribution[5] = {0}; // 90-100, 80-89, 70-79, 60-69, <60
for (int j = 0; j < studentCount; j++) {
if (students[j].scores[i] >= 0) {
if (students[j].scores[i] > max) max = students[j].scores[i];
if (students[j].scores[i] < min) min = students[j].scores[i];
sum += students[j].scores[i];
count++;
// 统计分数段
if (students[j].scores[i] >= 90) distribution[0]++;
else if (students[j].scores[i] >= 80) distribution[1]++;
else if (students[j].scores[i] >= 70) distribution[2]++;
else if (students[j].scores[i] >= 60) distribution[3]++;
else distribution[4]++;
}
}
if (count > 0) {
avg = sum / count;
printf("\n%s成绩统计:\n", subjectNames[i]);
printf("最高分:%.1f\n", max);
printf("最低分:%.1f\n", min);
printf("平均分:%.1f\n", avg);
printf("成绩分布:\n");
printf("90-100分:%d人 (%.1f%%)\n", distribution[0], (float)distribution[0]/count*100);
printf("80-89分:%d人 (%.1f%%)\n", distribution[1], (float)distribution[1]/count*100);
printf("70-79分:%d人 (%.1f%%)\n", distribution[2], (float)distribution[2]/count*100);
printf("60-69分:%d人 (%.1f%%)\n", distribution[3], (float)distribution[3]/count*100);
printf("60分以下:%d人 (%.1f%%)\n", distribution[4], (float)distribution[4]/count*100);
} else {
printf("\n%s:暂无成绩数据\n", subjectNames[i]);
}
}
// 总分和平均分统计
float maxTotal = -1, minTotal = 999999, sumTotal = 0;
float maxAvg = -1, minAvg = 999999, sumAvg = 0;
int validCount = 0;
for (int i = 0; i < studentCount; i++) {
if (students[i].total > 0) {
if (students[i].total > maxTotal) maxTotal = students[i].total;
if (students[i].total < minTotal) minTotal = students[i].total;
sumTotal += students[i].total;
if (students[i].average > maxAvg) maxAvg = students[i].average;
if (students[i].average < minAvg) minAvg = students[i].average;
sumAvg += students[i].average;
validCount++;
}
}
if (validCount > 0) {
printf("\n总分统计:\n");
printf("最高总分:%.1f\n", maxTotal);
printf("最低总分:%.1f\n", minTotal);
printf("平均总分:%.1f\n", sumTotal/validCount);
printf("\n平均分统计:\n");
printf("最高平均分:%.1f\n", maxAvg);
printf("最低平均分:%.1f\n", minAvg);
printf("总平均分:%.1f\n", sumAvg/validCount);
} else {
printf("\n暂无有效的成绩数据!\n");
}
}
// 成绩排序
void sortStudents() {
if (studentCount == 0) {
printf("\n没有学生数据可供排序!\n");
return;
}
printf("\n=== 成绩排序 ===\n");
printf("1. 按总分排序\n");
printf("2. 按平均分排序\n");
printf("3. 按单科成绩排序\n");
printf("请选择排序方式 (1-3): ");
int choice;
scanf("%d", &choice);
clearInputBuffer();
if (choice == 3) {
printf("\n请选择科目:\n");
for (int i = 0; i < subjectCount; i++) {
printf("%d. %s\n", i + 1, subjectNames[i]);
}
printf("请输入科目编号 (1-%d): ", subjectCount);
int subject;
scanf("%d", &subject);
clearInputBuffer();
if (subject < 1 || subject > subjectCount) {
printf("\n无效的科目选择!\n");
return;
}
subject--; // 转换为数组索引
// 使用快速排序按指定科目成绩排序
quickSort(students, 0, studentCount - 1);
// 更新排名
for (int i = 0; i < studentCount; i++) {
students[i].rank = i + 1;
}
printf("\n按%s成绩排序结果:\n", subjectNames[subject]);
displayHeader();
for (int i = 0; i < studentCount; i++) {
displayStudent(&students[i]);
}
} else if (choice == 1 || choice == 2) {
// 使用快速排序按总分或平均分排序
quickSort(students, 0, studentCount - 1);
// 更新排名
for (int i = 0; i < studentCount; i++) {
students[i].rank = i + 1;
}
printf("\n排序结果:\n");
displayHeader();
for (int i = 0; i < studentCount; i++) {
displayStudent(&students[i]);
}
} else {
printf("\n无效的选择!\n");
}
}
// 显示所有学生信息
void displayAllStudents() {
if (studentCount == 0) {
printf("\n当前没有学生数据!\n");
return;
}
printf("\n=== 所有学生信息 ===\n");
displayHeader();
for (int i = 0; i < studentCount; i++) {
displayStudent(&students[i]);
}
printf("\n共有 %d 名学生\n", studentCount);
}
// 生成成绩报告
void generateReport() {
printf("\n=== 生成成绩报告 ===\n");
printf("1. 生成班级成绩报告\n");
printf("2. 生成学科成绩报告\n");
printf("3. 导出成绩到CSV文件\n");
printf("请选择报告类型 (1-3): ");
int choice;
scanf("%d", &choice);
clearInputBuffer();
switch (choice) {
case 1:
generateClassReport();
break;
case 2:
generateSubjectReport();
break;
case 3:
exportToCsv();
break;
default:
printf("\n无效的选择!\n");
}
}
// 生成班级成绩报告
void generateClassReport() {
char className[MAX_NAME_LEN];
int found = 0;
printf("\n请输入要生成报告的班级: ");
scanf("%s", className);
clearInputBuffer();
// 创建报告文件
char filename[100];
sprintf(filename, "%s班级成绩报告.txt", className);
FILE *fp = fopen(filename, "w");
if (fp == NULL) {
printf("\n无法创建报告文件!\n");
return;
}
// 写入报告头部
fprintf(fp, "=== %s班级成绩报告 ===\n", className);
time_t now = time(NULL);
fprintf(fp, "生成时间:%s", ctime(&now));
// 统计数据
int classCount = 0;
float classTotalScore = 0;
float subjectTotals[MAX_SUBJECTS] = {0};
int subjectCounts[MAX_SUBJECTS] = {0};
// 收集数据
for (int i = 0; i < studentCount; i++) {
if (strcmp(students[i].className, className) == 0) {
found = 1;
classCount++;
classTotalScore += students[i].total;
for (int j = 0; j < subjectCount; j++) {
if (students[i].scores[j] >= 0) {
subjectTotals[j] += students[i].scores[j];
subjectCounts[j]++;
}
}
}
}
if (!found) {
fprintf(fp, "\n未找到该班级的学生信息!\n");
fclose(fp);
printf("\n未找到该班级的学生信息!\n");
return;
}
// 写入统计信息
fprintf(fp, "\n班级人数:%d\n", classCount);
fprintf(fp, "班级平均总分:%.2f\n\n", classTotalScore / classCount);
// 各科目统计
fprintf(fp, "各科目平均分:\n");
for (int i = 0; i < subjectCount; i++) {
if (subjectCounts[i] > 0) {
fprintf(fp, "%s:%.2f\n", subjectNames[i], subjectTotals[i] / subjectCounts[i]);
}
}
// 写入详细学生信息
fprintf(fp, "\n学生详细信息:\n");
fprintf(fp, "学号\t姓名\t性别\t");
for (int i = 0; i < subjectCount; i++) {
fprintf(fp, "%s\t", subjectNames[i]);
}
fprintf(fp, "总分\t平均分\t排名\n");
for (int i = 0; i < studentCount; i++) {
if (strcmp(students[i].className, className) == 0) {
fprintf(fp, "%s\t%s\t%c\t",
students[i].id,
students[i].name,
students[i].gender);
for (int j = 0; j < subjectCount; j++) {
if (students[i].scores[j] >= 0) {
fprintf(fp, "%.1f\t", students[i].scores[j]);
} else {
fprintf(fp, "N/A\t");
}
}
fprintf(fp, "%.1f\t%.1f\t%d\n",
students[i].total,
students[i].average,
students[i].rank);
}
}
fclose(fp);
printf("\n成绩报告已生成:%s\n", filename);
}
// 生成学科成绩报告
void generateSubjectReport() {
printf("\n请选择要生成报告的科目:\n");
for (int i = 0; i < subjectCount; i++) {
printf("%d. %s\n", i + 1, subjectNames[i]);
}
int choice;
printf("请输入科目编号 (1-%d): ", subjectCount);
scanf("%d", &choice);
clearInputBuffer();
if (choice < 1 || choice > subjectCount) {
printf("\n无效的科目选择!\n");
return;
}
int subjectIndex = choice - 1;
char filename[100];
sprintf(filename, "%s成绩报告.txt", subjectNames[subjectIndex]);
FILE *fp = fopen(filename, "w");
if (fp == NULL) {
printf("\n无法创建报告文件!\n");
return;
}
// 写入报告头部
fprintf(fp, "=== %s成绩报告 ===\n", subjectNames[subjectIndex]);
time_t now = time(NULL);
fprintf(fp, "生成时间:%s", ctime(&now));
// 统计数据
float max = -1, min = 101, sum = 0;
int count = 0;
int distribution[5] = {0}; // 90-100, 80-89, 70-79, 60-69, <60
// 统计分数分布
for (int i = 0; i < studentCount; i++) {
if (students[i].scores[subjectIndex] >= 0) {
float score = students[i].scores[subjectIndex];
if (score > max) max = score;
if (score < min) min = score;
sum += score;
count++;
if (score >= 90) distribution[0]++;
else if (score >= 80) distribution[1]++;
else if (score >= 70) distribution[2]++;
else if (score >= 60) distribution[3]++;
else distribution[4]++;
}
}
if (count == 0) {
fprintf(fp, "\n暂无成绩数据!\n");
fclose(fp);
printf("\n暂无成绩数据!\n");
return;
}
// 写入统计信息
fprintf(fp, "\n成绩统计:\n");
fprintf(fp, "最高分:%.1f\n", max);
fprintf(fp, "最低分:%.1f\n", min);
fprintf(fp, "平均分:%.1f\n", sum/count);
fprintf(fp, "\n成绩分布:\n");
fprintf(fp, "90-100分:%d人 (%.1f%%)\n", distribution[0], (float)distribution[0]/count*100);
fprintf(fp, "80-89分:%d人 (%.1f%%)\n", distribution[1], (float)distribution[1]/count*100);
fprintf(fp, "70-79分:%d人 (%.1f%%)\n", distribution[2], (float)distribution[2]/count*100);
fprintf(fp, "60-69分:%d人 (%.1f%%)\n", distribution[3], (float)distribution[3]/count*100);
fprintf(fp, "60分以下:%d人 (%.1f%%)\n", distribution[4], (float)distribution[4]/count*100);
// 写入详细成绩
fprintf(fp, "\n详细成绩:\n");
fprintf(fp, "学号\t姓名\t班级\t成绩\n");
for (int i = 0; i < studentCount; i++) {
if (students[i].scores[subjectIndex] >= 0) {
fprintf(fp, "%s\t%s\t%s\t%.1f\n",
students[i].id,
students[i].name,
students[i].className,
students[i].scores[subjectIndex]);
}
}
fclose(fp);
printf("\n成绩报告已生成:%s\n", filename);
}
// 导出成绩到CSV文件
void exportToCsv() {
char filename[100];
printf("\n请输入导出文件名(如 scores.csv): ");
scanf("%s", filename);
clearInputBuffer();
FILE *fp = fopen(filename, "w");
if (fp == NULL) {
printf("\n无法创建文件!\n");
return;
}
// 写入表头
fprintf(fp, "学号,姓名,性别,年龄,班级,");
for (int i = 0; i < subjectCount; i++) {
fprintf(fp, "%s,", subjectNames[i]);
}
fprintf(fp, "总分,平均分,排名\n");
// 写入学生数据
for (int i = 0; i < studentCount; i++) {
fprintf(fp, "%s,%s,%c,%d,%s,",
students[i].id,
students[i].name,
students[i].gender,
students[i].age,
students[i].className);
for (int j = 0; j < subjectCount; j++) {
if (students[i].scores[j] >= 0) {
fprintf(fp, "%.1f,", students[i].scores[j]);
} else {
fprintf(fp, "N/A,");
}
}
fprintf(fp, "%.1f,%.1f,%d\n",
students[i].total,
students[i].average,
students[i].rank);
}
fclose(fp);
printf("\n数据已成功导出到:%s\n", filename);
}
// 显示成绩分布直方图
void displayHistogram() {
if (studentCount == 0) {
printf("\n暂无学生数据!\n");
return;
}
printf("\n=== 成绩分布直方图 ===\n");
printf("请选择要显示的科目:\n");
for (int i = 0; i < subjectCount; i++) {
printf("%d. %s\n", i + 1, subjectNames[i]);
}
printf("%d. 总分\n", subjectCount + 1);
printf("%d. 平均分\n", subjectCount + 2);
int choice;
printf("请输入选择 (1-%d): ", subjectCount + 2);
scanf("%d", &choice);
clearInputBuffer();
if (choice < 1 || choice > subjectCount + 2) {
printf("\n无效的选择!\n");
return;
}
int distribution[5] = {0}; // 90-100, 80-89, 70-79, 60-69, <60
int validCount = 0;
float maxValue = 0;
// 统计分布
if (choice <= subjectCount) {
// 单科成绩分布
int subject = choice - 1;
for (int i = 0; i < studentCount; i++) {
if (students[i].scores[subject] >= 0) {
float score = students[i].scores[subject];
if (score >= 90) distribution[0]++;
else if (score >= 80) distribution[1]++;
else if (score >= 70) distribution[2]++;
else if (score >= 60) distribution[3]++;
else distribution[4]++;
validCount++;
}
}
printf("\n%s成绩分布:\n", subjectNames[subject]);
} else if (choice == subjectCount + 1) {
// 总分分布
for (int i = 0; i < studentCount; i++) {
if (students[i].total > 0) {
float score = students[i].total / (subjectCount * 100) * 100;
if (score >= 90) distribution[0]++;
else if (score >= 80) distribution[1]++;
else if (score >= 70) distribution[2]++;
else if (score >= 60) distribution[3]++;
else distribution[4]++;
validCount++;
}
}
printf("\n总分分布:\n");
} else {
// 平均分分布
for (int i = 0; i < studentCount; i++) {
if (students[i].average > 0) {
if (students[i].average >= 90) distribution[0]++;
else if (students[i].average >= 80) distribution[1]++;
else if (students[i].average >= 70) distribution[2]++;
else if (students[i].average >= 60) distribution[3]++;
else distribution[4]++;
validCount++;
}
}
printf("\n平均分分布:\n");
}
if (validCount == 0) {
printf("暂无有效数据!\n");
return;
}
// 找出最大值用于缩放
for (int i = 0; i < 5; i++) {
if (distribution[i] > maxValue) {
maxValue = distribution[i];
}
}
// 显示直方图
const int MAX_STARS = 50; // 最大显示宽度
const char* labels[] = {"90-100", "80-89", "70-79", "60-69", "<60"};
for (int i = 0; i < 5; i++) {
printf("%-7s |", labels[i]);
int stars = (int)((distribution[i] / maxValue) * MAX_STARS);
for (int j = 0; j < stars; j++) {
printf("*");
}
printf(" %d (%.1f%%)\n", distribution[i], (float)distribution[i]/validCount*100);
}
}
// 保存数据到文件
void saveToFile() {
FILE *fp = fopen(FILE_NAME, "wb");
if (fp == NULL) {
printf("\n无法保存数据!\n");
return;
}
fwrite(&studentCount, sizeof(int), 1, fp);
fwrite(students, sizeof(Student), studentCount, fp);
fclose(fp);
printf("\n数据保存成功!\n");
}
// 从文件加载数据
void loadFromFile() {
FILE *fp = fopen(FILE_NAME, "rb");
if (fp == NULL) {
printf("\n未找到数据文件,将创建新文件。\n");
return;
}
fread(&studentCount, sizeof(int), 1, fp);
fread(students, sizeof(Student), studentCount, fp);
fclose(fp);
printf("\n数据加载成功!\n");
}
// 显示表头
void displayHeader() {
printf("\n学号\t姓名\t性别\t年龄\t班级\t");
for (int i = 0; i < subjectCount; i++) {
printf("%s\t", subjectNames[i]);
}
printf("总分\t平均分\t排名\n");
printf("--------------------------------------------------------------------\n");
}
// 显示单个学生信息
void displayStudent(Student* student) {
printf("%s\t%s\t%c\t%d\t%s\t",
student->id,
student->name,
student->gender,
student->age,
student->className);
for (int i = 0; i < subjectCount; i++) {
if (student->scores[i] >= 0) {
printf("%.1f\t", student->scores[i]);
} else {
printf("N/A\t");
}
}
printf("%.1f\t%.1f\t%d\n",
student->total,
student->average,
student->rank);
}
// 验证输入
int validateInput(char* str, int type) {
if (strlen(str) == 0) return 0;
switch (type) {
case 1: // 学号
if (strlen(str) > MAX_ID_LEN - 1) return 0;
for (int i = 0; str[i]; i++) {
if (!isalnum(str[i])) return 0;
}
break;
case 2: // 姓名
if (strlen(str) > MAX_NAME_LEN - 1) return 0;
break;
}
return 1;
}
// 清除输入缓冲区
void clearInputBuffer() {
int c;
while ((c = getchar()) != '\n' && c != EOF);
}
// 计算平均分
float calculateAverage(float* scores)
{
float sum = 0;
int count = 0;
for (int i = 0; i < subjectCount; i++)
{
if (scores[i] >= 0) {
sum += scores[i];
count++;
}
}
return count > 0 ? sum / count : 0;
}
// 交换两个学生的位置
void swap(Student* a, Student* b)
{
Student temp = *a;
*a = *b;
*b = temp;
}
// 快速排序分区
int partition(Student* arr, int low, int high)
{
Student pivot = arr[high];
int i = low - 1;
for (int j = low; j < high; j++)
{
if (arr[j].total >= pivot.total)
{
i++;
swap(&arr[i], &arr[j]);
}
}
swap(&arr[i + 1], &arr[high]);
return i + 1;
}
// 快速排序
void quickSort(Student* arr, int low, int high)
{
if (low < high)
{
int pi = partition(arr, low, high);
quickSort(arr, low, pi - 1);
quickSort(arr, pi + 1, high);
}
}