一、设计目标:
学生成绩管理系统
利用结构体、排序查找算法以及模块化程序设计实现如下菜单驱动的学生成绩管理系统:
1)首次批量输入每个学生的学号、姓名、和各科考试成绩。
2)增添一个新学生的信息。
3)增添一门新的学科的信息。
4)按学生姓名或学号查询、修改、删除学生信息。
5)计算每门课程的总分和平均分。
6)计算每个学生的总分、平均分以及排名。
7)按总分从高到低(从低到高)排名并输出。
8)按学号大小排名并输出。
9)按学生姓名首字母排名并输出。
10)按优秀(90-100分)、良好(80-90分)、中等(70-80分)、及格(60-70分)、不及格(0-60分)5个类别,对每门课程分别统计每个类别的人数以及所占百分比。
11)输出每个学生的学号、姓名、各科考试成绩。
12)将每个学生的成绩写入文件。
13)从文件读取学生成绩并显示。
二、设计思路
本程序主要采用了、for循环完成录入、排序以及成绩筛选、函数、switch实现功能选择等方法。
图1 程序流程图
三.代码部分
/*Student scores mangement system V2.0Data structure Final-examinationWritten by Charles .11.7 - 11.25*/#include<stdio.h>#include<windows.h> #include<stdlib.h>#include<string.h> #include<stdbool.h> int n, course;typedef struct _student {char id[18]; //student idchar name[10];//student name float score[6]; //student scorefloat sum; //student sum scorefloat ave_stu;//student course average course}Student;typedef struct _Node //节点 {Student stu; //studentstruct _Node* pNext; //指向下一个指针 } Node;Node *g_pHead = NULL; //头节点void lth() //Low to high {Node *p = g_pHead, *p1;Student temp;int i, j;for(i = 0; i < n; i++){p = g_pHead;for(j = 0; j < n - i - 1;j++){p1 = p->pNext;if (p->stu.sum > p1->stu.sum){temp = p->stu;p->stu = p1->stu;p1->stu = temp;}p = p->pNext;}}for(i = 0; i < n; i++){p = g_pHead;for(j = 0; j < n - i - 1;j++){p1 = p->pNext;if (strcmp(p->stu.name, p1->stu.name) > 0 && p->stu.sum == p1->stu.sum){temp = p->stu;p->stu = p1->stu;p1->stu = temp;}p = p->pNext;}}}void htl() //High to low{Node *p = g_pHead, *p1;Student temp;int i, j;for(i = 0; i < n; i++){p = g_pHead;for(j = 0; j < n - i - 1; j++){p1 = p->pNext;if (p->stu.sum < p1->stu.sum){temp = p->stu;p->stu = p1->stu;p1->stu = temp;}p = p->pNext;}}for(i = 0;i < n;i++){p = g_pHead;for(j = 0; j < n - i - 1;j++){p1 = p->pNext;if (strcmp(p->stu.name, p1->stu.name) > 0 && p->stu.sum == p1->stu.sum){temp = p->stu;p->stu = p1->stu;p1->stu = temp;}p = p->pNext;}}} void idsort(){Node *p = g_pHead, *p1;Student temp;int i, j;for(i = 0; i < n; i++){p = g_pHead;for(j = 0; j < n - i - 1;j++){p1 = p->pNext;if (strcmp(p->stu.id, p1->stu.id) > 0){temp = p->stu;p->stu = p1->stu;p1->stu = temp;}p = p->pNext;}}} void namesort() // The first name sort {Node *p = g_pHead, *p1;Student temp;int i, j;for(i = 0; i < n; i++){p = g_pHead;for(j = 0; j < n - i - 1;j++){p1 = p->pNext;if (strcmp(p->stu.name, p1->stu.name) > 0){temp = p->stu;p->stu = p1->stu;p1->stu = temp;}p = p->pNext;}}}void save()// Save information to file {int i, j;Node *p = g_pHead;FILE *fp;lth();fp = fopen("内部文件.txt", "wt+"); fprintf(fp, "%d %d\n", n, course); for(i = 0; i < n; i++) {fprintf(fp, "%s %s ", p->stu.id, p->stu.name);for(j = 0; j < course; j++){fprintf(fp, "%.2f ", p->stu.score[j]);}fprintf(fp, "%.2f ", p->stu.sum);fprintf(fp, "%.2f\n", p->stu.ave_stu);p = p->pNext; }fclose(fp); } void readfile() // Read file information {g_pHead = NULL;FILE *fpp;fpp = fopen("内部文件.txt", "r+"); int i, j, k; char t; while (!feof(fpp)){fscanf(fpp, "%d%d", &n, &course);for(i = 0; i < n; i++){Node* pNewNode = (Node*)malloc(sizeof(Node)); //创建一个新的节点 pNewNode -> pNext = NULL; if(g_pHead == NULL){g_pHead = pNewNode;}else{pNewNode -> pNext = g_pHead;g_pHead = pNewNode; }for(j = 0; j < 18; j++){fscanf(fpp, "%c", &pNewNode->stu.id[j]);if(pNewNode->stu.id[j] == '\n'){j--;}if(pNewNode->stu.id[j] == ' '){pNewNode->stu.id[j] = '\0';break;} } for(j = 0; j < 10; j++){fscanf(fpp, "%c", &pNewNode->stu.name[j]);if(pNewNode->stu.name[j] == ' '){pNewNode->stu.name[j] = '\0';break;} }for(j = 0; j < course; j++){fscanf(fpp, "%f", &pNewNode->stu.score[j]);}fscanf(fpp, "%f", &pNewNode->stu.sum);fscanf(fpp, "%f\n", &pNewNode->stu.ave_stu);pNewNode = pNewNode->pNext;}}fclose(fpp); } void output(const char name[]) //Output the information{int i, j;FILE *fp;Node *p = g_pHead; fp = fopen(name, "wt+"); fprintf(fp, "———————————学生成绩表——————————————\n");fprintf(fp, "总排名 学号 姓名");for(j = 1; j < course; j++){fprintf(fp, "%9d ", j);} fprintf(fp, "%9d", course);fprintf(fp, " 总分平均分\n"); fprintf(fp, "——————————————————————————————\n");for(i = 0; i < n; i++) {fprintf(fp, "\n%3d、", i + 1);fprintf(fp, " %10s ", p->stu.id);fprintf(fp, "%10s ", p->stu.name);for(j = 0; j < course; j++){fprintf(fp, "%7.2f ", p->stu.score[j]);} fprintf(fp, "%7.2f %7.2f\n", p->stu.sum, p->stu.ave_stu);p = p->pNext;} fclose(fp); printf("-------------------------------------\n"); printf("已将文件存入%s\n", name);printf("-------------------------------------\n"); }void eachcour()// Add a new course {printf("-------------------------------------\n"); printf("请在出现的名字后面填写\n该同学的新增科目的成绩\n");printf("-------------------------------------\n"); int i;Node *p = g_pHead;for(i = 0; i < n; i++){printf("%s ", p->stu.name);scanf("%f", &p->stu.score[course]);p->stu.sum = p->stu.sum+ p->stu.score[course];p->stu.ave_stu = p->stu.sum / (course + 1); p = p->pNext;}course++;}void full()// Add a new student{int j;char t;Node* pNewNode = (Node*)malloc(sizeof(Node)); //创建一个新的节点 pNewNode -> pNext = g_pHead;g_pHead = pNewNode; printf("(eg:XXXXXXX(学号) XXXXXXXXX(姓名) XXX XXX XXX XXX(各科成绩) )\n"); printf("注意:当前可以输入的科目个数数为%d\n", course); scanf("%c", &t);for(j = 0; j < 18; j++){scanf("%c", &pNewNode->stu.id[j]);if(pNewNode->stu.id[j] == ' '){pNewNode->stu.id[j] = '\0';break;} } for(j = 0; j < 10; j++){scanf("%c", &pNewNode->stu.name[j]);if(pNewNode->stu.name[j] == ' '){pNewNode->stu.name[j] = '\0';break;} }pNewNode->stu.sum = 0;for(j = 0; j < course; j++){scanf("%f", &pNewNode->stu.score[j]);pNewNode->stu.sum = pNewNode->stu.sum + pNewNode->stu.score[j];}pNewNode->stu.ave_stu = pNewNode->stu.sum / course;n++; printf("-------------------------------------\n"); printf("已将该同学信息增加到程序中\n");printf("-------------------------------------\n"); }Node* findstu(const char a[2], int *c) //Find student information{int i, j, choise = 0, t = 0; char ex[30] = {'\0'};Node* p = g_pHead;printf("-------------------------------------\n"); printf(" 请选择查询类型:学号(1);姓名(2)\n");printf("-------------------------------------\n"); scanf("%d", &choise);if(choise == 1){while(1){printf("-------------------------------------\n"); printf(" 请输入需要%s学生信息的学号\n", a);printf("-------------------------------------\n"); scanf("%s", ex);p = g_pHead;for(i = 0; i < n; i++){if(strcmp(ex, p->stu.id) == 0){*c = i;return p;}p = p->pNext;}if(i == n){printf("-------------------------------------\n"); printf(" 输入学生信息有误或不存在,请重新输入\n");} }}else if(choise == 2){while(1){printf("-------------------------------------\n"); printf(" 请输入需要%s学生信息的姓名\n", a);printf("-------------------------------------\n"); scanf("%s", ex);p = g_pHead;for(i = 0; i < n; i++){if(strcmp(ex, p->stu.name) == 0){*c = i;return p; }p = p->pNext;}if(i == n){printf("-------------------------------------\n"); printf(" 输入学生信息有误或不存在,请重新输入\n");} }}}void showinfo(const char str[4])// Show student information{int i = 0, j; printf("-------------------------------------\n");printf("学生成绩信息显示 \n");printf("-------------------------------------\n");printf("当前显示模式为%s\n", str); printf("总排名学号姓名");for(j = 1; j < course; j++){printf("%6d ", j);} printf("%6d", course);printf("总分 平均分\n");printf("-------------------------------------\n"); Node* p = g_pHead;while(p != NULL){printf("\n%3d、", ++i);printf(" %10s ", p -> stu.id);printf("%10s ", p -> stu.name);for(j = 0; j < course; j++){printf("%-7.2f ", p -> stu.score [j]);} printf("%-7.2f %-7.2f\n", p->stu.sum, p->stu.ave_stu);p = p -> pNext; }}void sum() // Each courses` sum {Node *p = g_pHead;printf("-------------------------------------\n");printf(" 各个学科的成绩总和为\n"); printf("-------------------------------------\n"); int i, j;float sum[6] = {0};for(i = 0; i < course; i++){p = g_pHead;for(j = 0;j < n;j++){sum[i] = sum[i] + p->stu.score [i];p = p->pNext;}}for(i = 0; i < course; i++){printf("%d.科目%d:%.2f\n", i + 1, i + 1, sum[i] );}} void ave()//Each courses` average score {printf("-------------------------------------\n");printf(" 各个学科的平均分为\n"); printf("-------------------------------------\n"); int i, j;Node *p = g_pHead;float sum[6] = {0};for(i = 0; i < course; i++){p = g_pHead;for(j = 0;j < n;j++){sum[i] = sum[i] + p->stu.score [i];p = p->pNext;}}for(i = 0; i < course; i++){printf("%d.科目%d:%.2f\n", i + 1, i + 1, sum[i] / n);}}void max_() // Each courses` maxscore {printf("-------------------------------------\n");printf(" 各科最高分如下:\n");printf("-------------------------------------\n"); int i, j, max = 0;float t;Node *p = g_pHead, *p1;for(i = 0; i < course; i++){p = g_pHead;t = p->stu.score[i];for(j = 0; j < n; j++){if(t < p->stu.score[i]){t = p->stu.score[i];p1 = p;}p = p->pNext;}printf("%d.科目%d的最高分是:%s %.2f\n", i + 1, i + 1, p1->stu.name, p1->stu.score[i]);}} void presents() // Each course earch present {int i, j, nine, eight, seven, six, fail, t;Node *p = g_pHead;for(i = 0; i < course; i++){p = g_pHead;t = 0;nine = 0;eight = 0;seven = 0;six = 0;fail = 0;for(j = 0; j < n; j++){if(p->stu.score[i] > 100.00){p->stu.score[i] = p->stu.score[i] / 1.50;}p = p->pNext;}p = g_pHead;for(j = 0; j < n; j++){if(p->stu.score[i] <= 100.00 && p->stu.score[i] >= 90.00){nine++;}else if(p->stu.score[i] < 90.00 && p->stu.score[i] >= 80.00){eight++;}else if(p->stu.score[i] < 80.00 && p->stu.score[i] >= 70.00){seven++;}else if(p->stu.score[i] < 70.00 && p->stu.score[i] >= 60.00){six++;}else if(p->stu.score[i] < 60.00){fail++;}p = p->pNext;}printf("-------------------------------------\n"); printf("%d、科目%d输出结果如下:\n", i + 1, i + 1);printf("90-100:优秀的人数为%3d 占比为%.2f\n", nine, nine / (float)n);printf("80-90: 良好的人数为%3d 占比为%.2f\n", eight, eight / (float)n);printf("70-80: 一般的人数为%3d 占比为%.2f\n", seven, seven / (float)n);printf("60-70: 及格的人数为%3d 占比为%.2f\n", six, six / (float)n);printf("0-60: 不及格的人数为%3d 占比为%.2f\n", fail, fail / (float)n);printf("-------------------------------------\n"); }}void welcome() // The start page{system("cls");printf("-------------------------------------\n");printf("学生成绩管理系统 \n");printf("-------------------------------------\n");printf("请输入数字序列号,选择您要执行的操作\n");printf("0.录入学生信息\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("-------------------------------------\n");}void quitapp() // Quitapp {system("cls");printf("\n\n\n\n-------------------------------------\n");printf(" 欢迎下次使用( ̄︶ ̄)↗\n") ;printf("-------------------------------------\n\n\n\n"); system("pause"); exit(0);} void InputStudent() //学生信息录入{ int i, j, re;char t;system("cls");printf("-------------------------------------\n");printf(" 0.学生信息录入 \n");printf("-------------------------------------\n");printf("输入学生个数:\n"); scanf("%d", &n);printf("输入考试科目个数:\n");scanf("%d", &course);printf("输入学生信息:\n");printf("(eg:XXXXXXX(学号) XXXXXXXXX(姓名) XXX XXX XXX XXX(各科成绩) )\n"); for(i = 0; i < n; i++){Node* pNewNode = (Node*)malloc(sizeof(Node)); //创建一个新的节点 pNewNode -> pNext = NULL; if(g_pHead == NULL){g_pHead = pNewNode;}else{pNewNode -> pNext = g_pHead;g_pHead = pNewNode; }scanf("%c", &t);for(j = 0; j < 18; j++){scanf("%c", &pNewNode->stu.id[j]);if(pNewNode->stu.id[j] == ' '){pNewNode->stu.id[j] = '\0';break;} } for(j = 0; j < 10; j++){scanf("%c", &pNewNode->stu.name[j]);if(pNewNode->stu.name[j] == ' '){pNewNode->stu.name[j] = '\0';break;} }pNewNode->stu.sum = 0;for(j = 0; j < course; j++){scanf("%f", &pNewNode->stu.score[j]);pNewNode->stu.sum = pNewNode->stu.sum+ pNewNode->stu.score[j];}pNewNode->stu.ave_stu = pNewNode->stu.sum / course;} save();}void addinfo() //Add student`s information{int j, choice;readfile();system("cls");printf("-------------------------------------\n");printf(" 1.学生信息增添 \n");printf("-------------------------------------\n"); printf(" 请输入需要添加学生信息的类型:\n");printf("一个新的学生(1) 一门新的科目(2)\n");printf("-------------------------------------\n"); scanf("%d", &choice);switch(choice){case 1 : full();break;case 2 : eachcour();break;}save();printf("-------------------------------------\n"); printf(" 是否输出数据:是(1)否(0)\n");printf("-------------------------------------\n"); scanf("%d", &choice); switch(choice){case 1 : output("学生成绩表.txt"); break; case 0 : break;}}void deleteinfo() //Delete student`s information{int s, i, j, choise;char name[30] = {'\0'};Node *p1, *p2, *p_res;Node *p = NULL;readfile();system("cls");printf("-------------------------------------\n");printf(" 2.学生信息删除 \n");printf("-------------------------------------\n");p_res = findstu("删除", &s);strcpy(name, p_res->stu.name);printf("-------------------------------------\n");printf(" 是否将%s的信息删除:是(1) 否(0) \n", name);printf("-------------------------------------\n");scanf("%d", &choise); switch(choise){case 1 : if(strcmp(g_pHead->stu.name, name) == 0){p1 = g_pHead;g_pHead = g_pHead->pNext;free(p1); }else{p2 = g_pHead;while(p2 -> pNext != NULL){if(strcmp(p2->pNext->stu.name, name) == 0){p = p2->pNext;p2->pNext = p2->pNext->pNext;free(p);}p2 = p2->pNext;} }n--;printf("-------------------------------------\n"); printf(" 已将%s的信息删除\n", name);printf("-------------------------------------\n"); printf(" 是否输出数据:是(1)否(0)\n");printf("-------------------------------------\n"); scanf("%d", &choise); switch(choise){case 1 : output("学生成绩表.txt"); break; case 0 : break;}case 0 : break;}save();}void changeinfo() //Change student`s information{int i, j, *s, choice;char change[30] = {'\0'};float ch = 0.00;Node *p_res;readfile();system("cls");printf("-------------------------------------\n");printf(" 3.学生信息修改 \n");printf("-------------------------------------\n");p_res = findstu("修改", s);printf("-------------------------------------\n"); printf("请选择需要修改%s的信息选项:\n", p_res->stu.name);printf("学号(1), 姓名(2),成绩(3)\n");printf("-------------------------------------\n"); scanf("%d", &choice);switch(choice){case 1:printf("请输入新的学号:\n");scanf("%s", &p_res->stu.id);printf("-------------------------------------\n"); printf(" 已成功修改%s同学学号\n", p_res->stu.name); printf("-------------------------------------\n"); break;case 2:printf("请输入修改后的姓名:\n");scanf("%s", &p_res->stu.name);printf("-------------------------------------\n"); printf(" 已成功修改%s同学姓名\n", p_res->stu.name); printf("-------------------------------------\n"); break;case 3:printf("请输入想要修改的科目位号:(eg:科目一:1)\n");scanf("%d", &choice);printf("请输入修改后科目%d的分数:\n", choice);p_res->stu.sum = p_res->stu.sum - p_res->stu.score[choice - 1];scanf("%f", &p_res->stu.score[choice - 1]);p_res->stu.sum = p_res->stu.sum + p_res->stu.score[choice - 1];p_res->stu.ave_stu = p_res->stu.sum / course;}printf("-------------------------------------\n"); printf(" 是否输出数据:是(1)否(0)\n");printf("-------------------------------------\n"); scanf("%d", &choice); switch(choice){case 1 : break; case 0 : break;}save();}void searchinfo() //Search student`s information{int i, j, *s; Node *p_res;readfile();system("cls");printf("-------------------------------------\n");printf(" 4.学生信息查询 \n");printf("-------------------------------------\n");p_res = findstu("查询", s);printf("-------------------------------------\n");printf("总排名 学号 姓名");for(j = 1; j < course; j++){printf("%5d ", j);} printf("%5d", course);printf(" 总分 平均分\n");printf("-------------------------------------\n"); printf("\n%3d、", *s + 1);printf(" %10s ", p_res->stu.id);printf("%10s ", p_res->stu.name);for(j = 0; j < course; j++){printf("%5.2f ", p_res->stu.score[j]);} printf("%5.2f %5.2f\n", p_res->stu.sum, p_res->stu.ave_stu);}void infocount() //Information count{system("cls");readfile();printf("-------------------------------------\n");printf(" 5.学生成绩分析 \n");printf("-------------------------------------\n");int i, j, n, m, choice; printf("选择您需要的信息:(请输入数字)\n");printf("1. 各个学科的成绩总和\n"); printf("2. 各个学科的平均分\n"); printf("3. 各个学科的最高分\n");printf("4. 将成绩从低到高排序\n");printf("5. 将成绩从高到低排序\n");printf("6. 各科各个分数段组成占比\n");printf("-------------------------------------\n"); scanf("%d", &choice);switch(choice){case 1 : sum();break;case 2 : ave(); break; case 3 : max_(); break; case 4 : lth();break;case 5 : htl();break;case 6 : presents();break;}if(choice == 4 || choice == 5){printf("-------------------------------------\n"); printf(" 是否显示信息:是(1) 否(0)\n");printf("-------------------------------------\n"); scanf("%d", &n);switch(n){case 1 : switch(choice){case 4 : showinfo("从低到高");break; case 5 : showinfo("从高到低");break;}case 0 : break;}printf("-------------------------------------\n"); printf(" 是否输出数据:是(1)否(0)\n");printf("-------------------------------------\n"); scanf("%d", &n); switch(n){case 1 : switch(choice){case 4 : output("从低到高排序的成绩单.txt");break; case 5 : output("从高到低排序的成绩单.txt");break;} case 0 : break;}}}void outtxt(){int choice; readfile();system("cls");printf("-------------------------------------\n");printf(" 6.学生信息输出 \n");printf("-------------------------------------\n");printf("请输入输出模式:(填写数字)\n"); printf("1.成绩从高到低\n"); printf("2.成绩从低到高\n");printf("3.按姓名首字母排序\n");printf("4.按学号大小排序\n");printf("-------------------------------------\n");scanf("%d", &choice);switch(choice){case 1 : htl();output("从高到低排序的成绩单.txt");break;case 2 : lth();output("从低到高排序的成绩单.txt");break;case 3 : namesort();output("按名称首字母排序的成绩单.txt");break;case 4 : idsort(); output("按学号排序的成绩单.txt");break;}}int main(){int choice = 0, re;while(choice != 9) {system("cls");welcome();scanf("%d", & choice);switch(choice){case 0 : InputStudent(); //Input student informationbreak;case 1 : addinfo(); //Add student information break;case 2 : deleteinfo(); //Delete student informationbreak;case 3 : changeinfo(); //Change student informationbreak;case 4 : searchinfo(); //Search student information break;case 5 : infocount();//Information countbreak;case 6 : outtxt(); //Output txtbreak;case 7 : readfile();//Show classmates informationshowinfo("全体学生");break;case 8 : quitapp(); //Quit the applicationbreak;}printf("-------------------------------------\n");printf(" 操作成功,是否继续操作 \n");printf("-------------------------------------\n");printf(" 是:1 否:0 \n"); scanf("%d", &re); switch(re){case 1: ; break;case 0: choice = 9;break;}}quitapp();return 0;}