#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_STUDENT_SIZE 1000
struct Student {
char name[32];
char id[16];
int chinese_score;
int math_score;
int total_score;
};
struct Student students[MAX_STUDENT_SIZE];
int num_of_stu = 0; /*学生总人数*/
FILE* fp = NULL; /*保存学生信息的文件指针*/
/*函数申明*/
void load(); /*从文件加载学生成绩数据*/
int main_menu(); /*主菜单*/
void exit_system(); /*退出系统*/
void input_scores(); /*学生成绩录入*/
void rank_by_total_score(); /*按总分排名次*/
void query_by_name(); /*按姓名查找某学生成绩*/
void course_statistical_analyse(); /*统计各课程的平均分、及格率、最高分、最低分*/
void print_report_card(); /*打印成绩单*/
void print_report_card_by_name(); /*根据学生姓名打印成绩单*/
void print_report_card_by_id(); /*根据学生学号打印成绩单*/
int main() {
int option;
load(); /*从文件中读取所有已经录入的学生成绩信息*/
while (1) {
option = main_menu();
/*选项输入结束,处理具体事务*/
switch(option) {
case 0:
exit_system();
break;
case 1:
input_scores();
break;
case 2:
rank_by_total_score();
break;
case 3:
query_by_name();
break;
case 4:
course_statistical_analyse();
break;
case 5:
print_report_card();
break;
default:
exit_system();
break;
}
printf("\n\n1. 回到主菜单 0. 退出系统, 请选择您需要的选项:");
scanf("%d", &option);
if (option != 1) {
break;
}
}
if(fp != NULL) {
fclose(fp); /*关闭文件*/
}
return 0;
}
void load() {
/*读写打开一个二进制文件,允许读,或在文件末追加数据*/
fp = fopen("student_info.db", "ab+");
if (fp == NULL) {
perror("cannot open the file!");
exit(-1);
}
/*加载保存在文件中的学生成绩信息*/
fseek(fp, 0, SEEK_SET);
while(fread(&students[num_of_stu], sizeof(struct Student), 1, fp) == 1) {
num_of_stu++;
printf("%d\n", num_of_stu);
}
printf("%d\n", num_of_stu);
}
int main_menu() {
int option = 0;
system("cls");
printf("**********************学生成绩管理系统****************************\n");
printf("* 1. 录入学生成绩(姓名、学号、语文、数学成绩,总分自动计算)\n");
printf("* 2. 按总分排名次\n");
printf("* 3. 按姓名查找某学生成绩\n");
printf("* 4. 统计各课程的平均分、及格率、最高分、最低分\n");
printf("* 5. 打印成绩表\n");
printf("* 0. 退出系统\n");
printf("******************************************************************\n");
printf("请输入您需要的选项(0-5):");
scanf("%d", &option);
/*输入选项检查,选项必须是0-5,否则重新输入*/
while (option < 0 || option > 5) {
printf("输入的选项有误,请重新输入您需要的选项(0-5):");
scanf("%d", &option);
}
return option;
}
void exit_system() {
exit(0);
}
void input_scores() {
int sub_opt = 0;
while (1) {
/*录入学生成绩时,首先学生总数是否已达到系统上限*/
if (num_of_stu >= MAX_STUDENT_SIZE) {
/*学生总数达系统上限,退出成绩录入*/
printf("学生总数已达到系统上限(%d),无法录入学生成绩!", MAX_STUDENT_SIZE);
break;
}
printf("请输入学生姓名、学号、语文、数学成绩,基本格式如(张三 13091121 85 90):\n");
scanf("%s%s%d%d", students[num_of_stu].name,
students[num_of_stu].id,
&students[num_of_stu].chinese_score,
&students[num_of_stu].math_score);
/*判断语文成绩是否合法,成绩百分制*/
if (students[num_of_stu].chinese_score < 0 || students[num_of_stu].chinese_score > 100) {
printf("语文成绩(%d)有误!\n", students[num_of_stu].chinese_score);
printf("请重新录入该生成绩!\n");
continue;
}
/*判断数学成绩是否合法,成绩百分制*/
if (students[num_of_stu].math_score < 0 || students[num_of_stu].math_score > 100) {
printf("数学成绩(%d)有误!\n", students[num_of_stu].math_score);
printf("请重新录入该生成绩!\n");
continue;
}
students[num_of_stu].total_score
= students[num_of_stu].chinese_score + students[num_of_stu].math_score;
if (fp != NULL) {
/*录入学生成绩保存到文件中,系统启动时从文件加载所有录入的成绩*/
if (fwrite(&students[num_of_stu], sizeof(struct Student), 1, fp) != 1) {
perror("文件写入出错!");
exit(-1);
}
}
num_of_stu++; /*学生总数加1*/
/*判断是否继续录入学生成绩*/
printf("是否继续录入学生成绩,是(1), 否(0):");
scanf("%d", &sub_opt);
if (sub_opt != 1) { /*学生成绩录入结束*/
break;
}
}
}
/*按总分排名次*/
void rank_by_total_score(){
struct Student tmp_stu;
for (int i = 0; i < num_of_stu - 1; i++) {
for (int j = 0; j < num_of_stu - 1 - i; j++) {
if (students[j].total_score > students[j+1].total_score) {
memcpy(&tmp_stu, &students[j],sizeof(struct Student));
memcpy(&students[j], &students[j+1], sizeof(struct Student));
memcpy(&students[j+1], &tmp_stu, sizeof(struct Student));
}
}
}
printf("--------------------------------------------------------------------------\n");
printf(" 姓名 学号 语文 数学 总分\n");
for (int j = 0; j < num_of_stu; j++) {
printf("%16s%16s%10d%10d%10d\n", students[j].name,
students[j].id,
students[j].chinese_score,
students[j].math_score,
students[j].total_score);
}
printf("--------------------------------------------------------------------------\n");
}
void query_by_name(){
char name[32];
int cnt = 0 ;
printf("请输入需要查询成绩的学生姓名:");
scanf("%s", name);
for (int i = 0; i < num_of_stu; i++) {
if(strcmp(students[i].name, name) == 0) {
if (cnt == 0){ /*可能存在同名同姓的同学,只有查找到第一个学生的时候输出表头*/
printf("--------------------------------------------------------------------------\n");
printf(" 姓名 学号 语文 数学 总分\n");
}
printf("%16s%16s%10d%10d%10d\n", students[i].name,
students[i].id,
students[i].chinese_score,
students[i].math_score,
students[i].total_score);
cnt++;
}
}
if (cnt == 0) {
printf("学生成绩管理系统中不存在姓名为的\"%s\"学生\n", name);
}
else {
printf("--------------------------------------------------------------------------\n");
}
}
void course_statistical_analyse(){
if (num_of_stu == 0) { /*学生总数为0时,单独处理,计算平均分和及格率时除0程序会出现错误*/
printf("学生总数:0\n");
printf("语文成绩统计情况:\n");
printf("\t均分:0\n");
printf("\t及格率:0\n");
printf("\t最高分:0\n");
printf("\t最低分:0\n");
printf("数学成绩统计情况:\n");
printf("\t均分:0\n");
printf("\t及格率:0\n");
printf("\t最高分:0\n");
printf("\t最低分:0\n");
return;
}
double total_chinese_scores = 0;
double total_math_scores = 0;
int max_chinese_score = students[0].chinese_score;
int max_math_score = students[0].math_score;
int min_chinese_score = students[0].chinese_score;
int min_math_score = students[0].math_score;
int chinese_passes = 0;
int math_passes = 0;
for (int i = 0; i < num_of_stu; i++) {
/*统计总分*/
total_chinese_scores += students[i].chinese_score;
total_math_scores += students[i].math_score;
/*统计最高分和最低分*/
if (students[i].chinese_score > max_chinese_score) {
max_chinese_score = students[i].chinese_score;
}
else if (students[i].chinese_score < min_chinese_score) {
min_chinese_score = students[i].chinese_score;
}
if (students[i].math_score > max_math_score) {
max_math_score = students[i].math_score;
}
else if (students[i].math_score < min_math_score) {
min_math_score = students[i].math_score;
}
/*统计及格率*/
if (students[i].chinese_score >= 60) {
chinese_passes++;
}
if (students[i].math_score >= 60) {
math_passes++;
}
}
printf("学生总数:%d\n", num_of_stu);
printf("语文成绩统计情况:\n");
printf("\t均分:%.2lf\n", total_chinese_scores / num_of_stu); /*只保留两位小数*/
printf("\t及格率:%.2lf%%\n", chinese_passes*100.0 /num_of_stu);/*只保留两位小数,百分比*/
printf("\t最高分:%d\n", max_chinese_score);
printf("\t最低分:%d\n", min_chinese_score);
printf("数学成绩统计情况:\n");
printf("\t均分:%.2lf\n", total_math_scores / num_of_stu);
printf("\t及格率:%.2lf%%\n", math_passes*100.0 / num_of_stu);
printf("\t最高分:%d\n", max_math_score);
printf("\t最低分:%d\n", min_math_score);
}
void print_report_card(){
int sub_opt = 1;
printf("1.按学号打印成绩单 2.按姓名打印成绩单\n");
printf("请输入您需要的选项(1-2):");
scanf("%d", &sub_opt);
while (sub_opt < 1 ||sub_opt > 2) {
printf("输入选项(%d)不存在!", sub_opt);
printf("1.按学号打印成绩单 2.按姓名打印成绩单\n");
printf("请重新输入您需要的选项(1-2):");
scanf("%d", &sub_opt);
}
switch(sub_opt) {
case 1:
print_report_card_by_id();
break;
case 2:
print_report_card_by_name();
break;
}
}
void print_report_card_by_name() {
char name[32];
int cnt = 0;
printf("请输入需要打印成绩的学生姓名:");
scanf("%s", name);
for (int i = 0; i < num_of_stu; i++) {
if(strcmp(students[i].name, name) == 0) {
printf("\n---------------------------------成绩单------------------------------------\n");
printf("姓名:%s\t学号:%s\n", students[i].name, students[i].id);
printf("语文:%d\n", students[i].chinese_score);
printf("数学:%d\n", students[i].math_score);
printf("总分:%d\n", students[i].total_score);
printf("--------------------------------------------------------------------------\n");
cnt++;
}
}
if (cnt == 0) {
printf("不存在姓名为\"%s\"的学生", name);
}
}
void print_report_card_by_id() {
char id[16];
printf("请输入需要打印成绩单的学生学号:");
scanf("%s", id);
int i;
for (i = 0; i < num_of_stu; i++) {
if(strcmp(students[i].id, id) == 0) {
printf("\n---------------------------------成绩单------------------------------------\n");
printf("姓名:%s\t学号:%s\n", students[i].name, students[i].id);
printf("语文:%d\n", students[i].chinese_score);
printf("数学:%d\n", students[i].math_score);
printf("总分:%d\n", students[i].total_score);
printf("--------------------------------------------------------------------------\n");
break;
}
}
if (i == num_of_stu) {
printf("不存在学号为\"%s\"的学生", id);
}
}