学生成绩管理系统的设计与实现

时间:2025-02-19 08:10:20
#include <> #include <> #include <> #define max_size 30 //学生最大容量 #define max_course 6 //课程最大数量 typedef struct { //学生的信息 int *grades; int number; //学号 char *name; int sum_gardes; double ave_grade; } StudentTp; typedef struct node { //链表结点结构体 StudentTp data; struct node *next; } LNode, *Node; void main() { //函数声明 void Input_record(char **s, Node h, int &total_course, int &total_student); void Calculate_total_average(char **s, Node h, int &total_course, int &total_student); void Calculate_students_total_average(Node h, int &total_course, int &total_student); void Sort_in_up_order(Node h, int &total_course, int &total_student); void Sort_in_down_order(Node h, int &total_course, int &total_student); void Sort_ByNumber(Node h); void Sort_ByDictionary(Node h); void Search_ByNumber(Node h, int &number, int &total_course, int &total_student); void Search_ByName(Node h, char *name, int &total_course, int &total_student); void Statistic_Analysis(Node h, char **s, int &total_course, int &total_student); void List_Record(Node h, char **s, int &total_course, int &total_student); void Write_to_a_file(Node h, char **s, int &total_course, int &total_student); void Read_from_a_file(char **s, Node h, int &total_course, int &total_student); int total_student = 0; //用于记录已经录入的学生人数 int total_course = 0; //用于记录已经录入的课程数 //初始化必要的信息 Node h; h = (Node)malloc(sizeof(LNode)); h->next = NULL; //初始化头结点 int i; printf("请输入课程数:"); scanf("%d", &total_course); //初始化课程信息 printf("请输入课程名(用空格隔开):"); char **a = (char **)malloc(total_course * sizeof(char *)); for (i = 0; i < total_course; i++) *(a + i) = (char *)malloc(10); for (i = 0; i < total_course; i++) scanf("%s", *(a + i)); //菜单栏用switch-case语句实现 int menu; do { printf("********************学生成绩管理系统********************\n"); printf(" record\n"); printf(" total and average score of every course\n"); printf(" total and average score of every student\n"); printf(" in descending order by total score of every student\n"); printf(" in ascending order by total score of every student\n"); printf(" in ascending order by number\n"); printf(" in dictionary order by name\n"); printf(" by number\n"); printf(" by name\n"); printf(" analysis for every course\n"); printf(" record\n"); printf(" to a file\n"); printf(" from a file\n"); printf("\n"); printf("Please enter your choice:"); scanf("%d", &menu); printf("********************学生成绩管理系统********************\n"); switch (menu) { case 1: Input_record(a, h, total_course, total_student); break; case 2: if (h->next == NULL) { printf("未录入学生信息!\n"); break; } else { Calculate_total_average(a, h, total_course, total_student); break; } case 3: if (h->next == NULL) { printf("未录入学生信息!\n"); break; } else { Calculate_students_total_average(h, total_course, total_student); printf("计算成功!\n\n"); break; } case 4: if (h->next == NULL) { printf("未录入学生信息!\n"); break; } else { Sort_in_down_order(h, total_course, total_student); int order = 0; Node p; for (p = h; p->next; p = p->next) printf("第%d名:%s,总分为:%d\n", ++order, p->next->data.name, p->next->data.sum_gardes); printf("\n\n"); break; } case 5: if (h->next == NULL) { printf("未录入学生信息!\n"); break; } else { Sort_in_up_order(h, total_course, total_student); int order = total_student; Node p; for (p = h; p->next; p = p->next) printf("第%d名:%s,总分为:%d\n", order--, p->next->data.name, p->next->data.sum_gardes); printf("\n\n"); break; } case 6: if (h->next == NULL) { printf("未录入学生信息!\n"); break; } else { Sort_ByNumber(h); break; } case 7: if (h->next == NULL) { printf("未录入学生信息!\n"); break; } else { Sort_ByDictionary(h); break; } case 8: if (h->next == NULL) { printf("未录入学生信息!\n"); break; } else { printf("请输入要查找的学号:"); int number; scanf("%d", &number); Search_ByNumber(h, number, total_course, total_student); break; } case 9: if (h->next == NULL) { printf("未录入学生信息!\n"); break; } else { printf("请输入要查找的姓名:"); char *name = (char *)malloc(10); scanf("%s", name); Search_ByName(h, name, total_course, total_student); free(name); break; } case 10: if (h->next == NULL) { printf("未录入学生信息!\n"); break; } else { Statistic_Analysis(h, a, total_course, total_student); break; } case 11: if (h->next == NULL) { printf("未录入学生信息!\n"); break; } else { List_Record(h, a, total_course, total_student); break; } case 12: Write_to_a_file(h, a, total_course, total_student); break; case 13: Read_from_a_file(a, h, total_course, total_student); break; case 0: break; } } while (menu != 0); free(h); free(a); } void Input_record(char **s, Node h, int &total_course, int &total_student) { /*二重指针用于传递课程名,total_course用于传递课程数,total_student用于传递学生总数 这里不是pure C,借用了C++的引用,有类似于全局变量的作用 */ int n, i; Node p; //扫描指针,准备用头插法插入结点 Node r; //待插入的结点 p = h; printf("请输入学生人数:"); scanf("%d", &n); //同时记录学生人数 total_student = total_student + n; //n用于插入结点时记录剩余插入的结点数 printf("请按以下顺序输入学生信息:姓名,学号"); for (i = 0; i < total_course; i++) printf(",%s", *(s + i)); printf("\n"); while (n) { //以下初始化待插入结点的信息 r = (Node)malloc(sizeof(LNode)); r->next = NULL; r->data.name = (char *)malloc(10); r->data.grades = (int *)malloc(total_course); scanf("%s %d", r->data.name, &r->data.number); for (i = 0; i < total_course; i++) scanf("%d", &r->data.grades[i]); //以下插入该结点 if (p == h) { p->next = r; p = r; } else { h->next = r; r->next = p; p = r; } n--; } printf("录入成功!\n\n"); } void Calculate_total_average(char **s, Node h, int &total_course, int &total_student) { //计算每门课程的总分 Node p; //扫描指针 double *sum = (double *)malloc(total_course * sizeof(double)); int i; for (i = 0; i < total_course; i++) sum[i] = 0; //求和数组初始化 for (i = 0; i < total_course; i++) { //以下对和数组赋值 p = h; while (p->next) { sum[i] = sum[i] + p->next->data.grades[i]; p = p->next; } } for (i = 0; i < total_course; i++) { printf("%s课程的总分为:%\n", *(s + i), sum[i]); printf("%s课程的平均分为:%8.3lf\n", *(s + i), sum[i] / total_student * 1.0); } free(sum); } void Calculate_students_total_average(Node h, int &total_course, int &total_student) { //计算每个学生的总分和平均分并保存 Node p; //扫描指针 double *sum = (double *)malloc(total_student * sizeof(double)); int i, j; for (i = 0; i < total_student; i++) sum[i] = 0; //求和数组初始化 for (i = 0, p = h; i < total_student, p->next; i++, p = p->next) for (j = 0; j < total_course; j++) sum[i] = sum[i] + p->next->data.grades[j]; //以下将sum数组的值存入学生的个人信息 for (i = 0, p = h; i < total_student, p->next; i++, p = p->next) { p->next->data.sum_gardes = sum[i]; p->next->data.ave_grade = sum[i] / total_course * 1.0; } free(sum); } void Sort_in_up_order(Node h, int &total_course, int &total_student) { Calculate_students_total_average(h, total_course, total_student); //以下开始升序排序(总分由低到高) Node p, r, s, pr; r = h->next; h->next = NULL; //断开头结点 while (r) { s = r; //“摘下”结点r给s r = r->next; pr = h; p = h->next; //初始化主、从动指针 //以下将取下的s结点插入到以head为头结点的链表中 while (p && p->data.sum_gardes < s->data.sum_gardes) { //当p->data.sum_gardes第一次大于s->data.sum_gardes时跳出循环 pr = p; p = p->next; } //开始插入 pr->next = s; s->next = p; } } void Sort_in_down_order(Node h, int &total_course, int &total_student) { Calculate_students_total_average(h, total_course, total_student); //以下开始降序排序(总分由高到低) Node p, r, s, pr; r = h->next; h->next = NULL; //断开头结点 while (r) { s = r; //“摘下”结点r给s r = r->next; pr = h; p = h->next; //初始化主、从动指针 //以下将取下的s结点插入到以head为头结点的链表中 while (p && p->data.sum_gardes > s->data.sum_gardes) { //当p->data.sum_gardes第一次小于s->data.sum_gardes时跳出循环 pr = p; p = p->next; } //开始插入 pr->next = s; s->next = p; } } //这两个排序也可以求其中之一然后利用"逆置"算法来求另一个;或者求其中一个,然后倒序输出另外一个 void Sort_ByNumber(Node h) { //按学号升序排列 Node p, r, s, pr; r = h->next; h->next = NULL; //断开头结点 while (r) { s = r; //“摘下”结点r给s r = r->next; pr = h; p = h->next; //初始化主、从动指针 //以下将取下的s结点插入到以head为头结点的链表中 while (p && p->data.number < s->data.number) { //当p->第一次大于s->时跳出循环 pr = p; p = p->next; } //开始插入 pr->next = s; s->next = p; } for (p = h; p->next; p = p->next) printf("姓名:%s 学号:%d 总分:%d\n", p->next->data.name, p->next->data.number, p->next->data.sum_gardes); printf("\n\n"); } void Sort_ByDictionary(Node h) { //按姓名的字典顺序排列 Node p, r, s, pr; r = h->next; h->next = NULL; //断开头结点 while (r) { s = r; //“摘下”结点r给s r = r->next; pr = h; p = h->next; //初始化主、从动指针 //以下将取下的s结点插入到以head为头结点的链表中 while (p && strcmp(p->data.name, s->data.name) < 0) { //当p->第一次大于s->时跳出循环 pr = p; p = p->next; } //开始插入 pr->next = s; s->next = p; } for (p = h; p->next; p = p->next) printf("姓名:%s 学号:%d 总分:%d\n", p->next->data.name, p->next->data.number, p->next->data.sum_gardes); printf("\n\n"); } void Search_ByNumber(Node h, int &number, int &total_course, int &total_student) { //查询的成绩假定是按总分从高到低 Sort_in_down_order(h, total_course, total_student); Node p; int i = 0; for (p = h; p->next; p = p->next) { i++; if (p->next->data.number == number) { printf("该学生是第%d名 总分为:%d\n", i, p->next->data.sum_gardes); printf("\n\n"); break; } } if (i >= total_student) printf("没有该生的成绩!\n"); printf("\n"); } void Search_ByName(Node h, char *name, int &total_course, int &total_student) { //查询的成绩假定是按总分从高到低 Sort_in_down_order(h, total_course, total_student); Node p; int i = 0; for (p = h; p->next; p = p->next) { i++; if (strcmp(p->next->data.name, name) == 0) { printf("该学生是第%d名 总分为:%d\n", i, p->next->data.sum_gardes); printf("\n\n"); break; } } if (i >= total_student) printf("没有该生的成绩!\n"); printf("\n"); } void Statistic_Analysis(Node h, char **s, int &total_course, int &total_student) { int i; //i表示第i门课 int A[max_course] = {0}, B[max_course] = {0}, C[max_course] = {0}, D[max_course] = {0}, E[max_course] = {0}; Node p; for (i = 0; i < total_course; i++) { p = h; while (p->next) { if (p->next->data.grades[i] >= 90 && p->next->data.grades[i] <= 100) A[i]++; else if (p->next->data.grades[i] >= 80) B[i]++; else if (p->next->data.grades[i] >= 70) C[i]++; else if (p->next->data.grades[i] >= 60) D[i]++; else if (p->next->data.grades[i] < 60 && p->next->data.grades[i] >= 0) E[i]++; p = p->next; } } for (i = 0; i < total_course; i++) printf("%s:优秀%d人,占%5.2lf%% 良好%d人,占%5.2lf%% 中等%d人,占%5.2lf%% 及格%d人,占%5.2lf%% 不及格%d人,占%5.2lf%%\n", *(s + i), A[i], A[i] * 100.0 / total_student, B[i], B[i] * 100.0 / total_student, C[i], C[i] * 100.0 / total_student, D[i], D[i] * 100.0 / total_student, E[i], E[i] * 100.0 / total_student); printf("\n\n"); } void List_Record(Node h, char **s, int &total_course, int &total_student) { Calculate_students_total_average(h, total_course, total_student); int i, j; Node p; for (i = 0, p = h; i < total_student, p->next; i++, p = p->next) { printf("姓名:%s 学号:%d ", p->next->data.name, p->next->data.number); for (j = 0; j < total_course; j++) printf("%s:%d分 ", *(s + j), p->next->data.grades[j]); printf("总分:%d 平均分:%8.3lf\n", p->next->data.sum_gardes, p->next->data.ave_grade); } printf("\n\n"); } void Write_to_a_file(Node h, char **s, int &total_course, int &total_student) { //只是在输出学生信息的函数里加了一个打开文件和关闭文件的操作 freopen("Debug\\", "w", stdout); List_Record(h, s, total_course, total_student); fclose(stdout); } void Read_from_a_file(char **s, Node h, int &total_course, int &total_student) { //只是在录入学生信息的函数里加了一个打开文件和关闭文件的操作 freopen("Debug\\", "r", stdin); Input_record(s, h, total_course, total_student); fclose(stdout); }