一、设计目的

随着信息技术的发展,过去很多由人工处理的复杂事务开始由计算机来完成,学生成绩管理系统利用计算机对学生成绩进行统一的管理,实现完善的学生成绩录人、维护、统计、排序、保存到文件、打开成绩文件等管理工作,从而节约时间,提高教务人员的工作效率。

二、需求分析

本学生成绩管理系统可以实现对众多学生信息的统一管理,其中记录的学生信息包括学生的学号、姓名、语文成绩、数学成绩、英语成绩、三门课程的平均成绩和平均成绩排名。具体功能需求描述如下。

(1)录人学生成绩信息:能够录人学生学号、姓名、语文成绩、数学成绩、英语成绩,并支持一次性录人多条学生成绩记录。

(2)将成绩信息保存到文件:能够将录人的学生成绩信息,以及计算得出的平均成绩、排名等信息永久记录到硬盘文件中。

(3)从文件中读取成绩信息:可以输人文件名,读取文件中的学生成绩信息并显示到界面,并可以进一步对读出的信息进行操作。(4)添加学生记录:可以连续添加多个学生记录,如果之前一条记录也没有,则提示用户先创建学生记录。

(5)删除学生记录:可以根据学生学号或者姓名查找要删除的学生记录,如果找到该记录,则将该学生记录删除。

(6)修改学生记录:可以根据学生学号或者姓名查找要修改的学生记录,如果找到该记录,则可以对该记录的各个字段进行修改。

(7)查找学生记录:可以按学号查找或者按姓名查找学生记录。

(8)学生成绩统计:可以对每门课程的通过人数、不及格人数、最低分、最高分、平均分,以及所有课程的最低分、最高分、平均分进行详细统计。

(9)学生记录排序:可以分别按照学号、姓名、语文成绩、数学成绩、英语成绩或者平均成绩进行排序。

(10)显示所有学生记录:显示所有学生记录的各项信息。

三、总体设计

学生成绩管理系统的功能结构图如图所示,主要包括5个功能模块,分别介绍如下。

(1)学生成绩录人模块:成绩录人包括没有记录时的新建操作,以及已有记录时的涂加操作。对录人的学生学号进行判断,学号必须为大于等于0的数字,如果不满足要求,则提示用户重新输人;如果录人学号0,表示成绩录人结束。系统自动判断录人的学号是否与已有记录中的学生学号冲突,若冲突,则提示用户重新录人。一条学生记录的所有信息均录人完成之后,系统还会询问是否继续录人其他学生记录,支持学生信息的连续录人。

(2)学生成绩查询模块:学生成绩查询包括查看所有学生记录和查看某一个学生的记录。查看所有学生记录能以列表方式将系统中所有学生记录均显示出来;查看某一个学生的记录,则可以通过输人学号或者姓名信息进行查找,一旦找到对应记录,则显示该记录的所有信息,如果找不到,则提示用户。

(3)学生成绩维护模块:学生成绩维护包括常规的删除记录和修改记录。这两项功能要基于学生信息查询模块中的记录查找功能,一旦查找到要删除或者修改的记录,则可以执行相应的操作。

(4)排序与统计模块:能够对系统中的学生记录进行排序和统计。可以分别按照学号、姓名、语文成绩、数学成绩、英语成绩或者平均成绩进行排序;可以对每门课程的通过人数、不及格人数、最低分、最高分、平均分,以及所有课程的最低分、最高分、平均分进行详细的统计分析。

(5)文件存取模块:可以将系统中的学生成绩信息一次性存人磁盘文件中,文件名允许自定义。并且可以输人一个文件名,将该文件中的学生记录读出并显示在屏幕上。

四、详细设计与实现

1.数据的存储结构

定义的结构体如下:

typedef struct Student

{

char name[20]; //姓名

int S_Number; //学号

float Sorce_Chinese;

float Sorce_Math;

float Sorce_English;

float avg; //平均分

int iRank;//排名

struct Student* pNext;

}Student;

2.函数之间的调用关系

  1. void showMainMenu();

功能:打印主界面,显示功能选项

  1. Student* Create();

功能:创建学生记录,返回学生结构体类型的指针

  1. void Add(Student* pHead);

功能:向已有的数据表中添加数据

参数:一个已有的链表指针

  1. void Show(Student* pHead);

功能:显示数据表中的所有信息

参数:一个已有的链表指针

  1. void Sreach(Student* pHead);

功能:在数据表中搜索信息,找到显示该学生信息,没有找到则给出提示

参数:一个已有的链表指针

  1. void Modify(Student* pHead);

功能:在数据表中搜索信息,找到后修改信息,没有找到则给出提示

参数:一个已有的链表指针

  1. Student* Delete(Student* pHead);

功能:删除一个学生记录,先查找,若无则给出提示

参数:一个已有的链表指针

  1. void Sort();

功能:按照某个字段来排序

  1. void Statistics();

功能:统计数据表中的信息,分析各科成绩情况

  1. Student* Read();

功能:从文件读取信息

  1. void Save();

功能:保存数据表到本地,可以二进制保存或文本格式保存

  1. int CheakNum(char* pcNotice);

功能:检查学号输入是否正确

参数:字符串:一段提示信息

  1. float CheakScore(char* pcNotice);

功能:检查成绩输入是否正确

参数:字符串:一段提示信息

  1. void ShowHead(int iType);

功能:打印一段表头

参数:表头格式分两种

  1. void ShowSortMenu();

功能:显示排序功能选项

3.源代码

main.c

#define _CRT_SECURE_NO_WARNINGS#pragma once#include#include#include#include#include#include"Student.h"//#include"access.h"int main(){modeset(80, 49);/*int key=access();if (key == 0){return 0;}*/Student* pHead = NULL;int iItem;while (1){showMainMenu();printf("\n请输入要执行的功能选项:");scanf("%d", &iItem);while (iItem > 10 || iItem < 0){char c;printf("输入有误请重新输入:");while ((c = getchar()) != EOF && c != '\n');scanf("%d", &iItem);}switch (iItem){case 1:pHead = Create(); break;case 2:Add(pHead); break;case 3:Show(pHead); break;case 4:Sreach(pHead); break;case 5:Modify(pHead); break;case 6:pHead = Delete(pHead); break;case 7:Sort(pHead); break;case 8:Statistics(pHead); break;case 9:pHead = Read(); break;case 10:Save(pHead); break;case 0:exit(0); break;}for (int i = 0; i < 80; i++){printf("-");}printf("\n");printf("按任意键返回主页\n");getchar();}return 0;}

Student.c

#define _CRT_SECURE_NO_WARNINGS#pragma once#include#include#include#include #include #include"Student.h"void modeset(int w, int h){HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);//获取标准输出的句柄,命令行的程序会把字符输出到屏幕上。COORD size = { w, h };//设置窗口的大小。SetConsoleScreenBufferSize(hOut, size);//重新设置缓冲区大小。SMALL_RECT rc = { 1,1, w, h };//重置窗口位置和大小。SetConsoleWindowInfo(hOut, 1, &rc);//重置窗口大小system("cls");//清理屏幕return;}void Print(char c, int n, int flag){for (int i = 0; i < n; i++){printf("%c", c);}if (flag) {printf("\n");}}void showMainMenu(){system("cls");printf("\n\t\t\t\t学生成绩管理系统\n\n");Print('*', 80, 1);printf("1.创建记录\t\t5.更改数据\t\t9.从文件读取数据\n");printf("2.添加数据\t\t6.删除数据\t\t10.保存数据\n");printf("---------\t\t---------\t\t---------\n");printf("3.显示数据\t\t7.数据排序\t\t0.退出\n");printf("4.查找数据\t\t8.统计数据\n");Print('*', 80, 1);}void SwapStu(Student* Stu_1, Student* Stu_2){Student tmp;tmp = *Stu_1;*Stu_1 = *Stu_2;*Stu_2 = tmp;}int CheakNum(char* pcNotice){int inum;do {printf(pcNotice);scanf("%d", &inum);if (inum < 0){printf("学号有误请重新输入!\n");char c;while ((c = getchar()) != EOF && c != '\n');}} while (inum  100 || iScore  100 || iScore < 0);return iScore;}Student* Create(){Student* pHead = NULL, * pTail = NULL, * pTemp, * pCur;int iNum, iFlag;while (1){while (1){iNum = CheakNum("请输入学生学号:");if (iNum == 0){printf("输入结束!\n");Show(pHead);return pHead;}iFlag = 0;pCur = pHead;while (pCur != NULL){if (pCur->S_Number == iNum){iFlag = 1;break;}pCur = pCur->pNext;}if (iFlag == 1){printf("学号输入与他人重复,请重新输入!\n");continue;}elsebreak;}pTemp = (Student*)malloc(sizeof(Student));if (pTemp == NULL){printf("内存申请失败!");return NULL;}pTemp->S_Number = iNum;printf("请输入姓名:");char c;while ((c = getchar()) != EOF && c != '\n');scanf("%s", pTemp->name);getchar();pTemp->Sorce_Chinese = CheakScore("请输入语文成绩(0~100):");pTemp->Sorce_Math = CheakScore("请输入数学成绩(0~100):");pTemp->Sorce_English = CheakScore("请输入英语成绩(0~100):");pTemp->avg = (pTemp->Sorce_Chinese + pTemp->Sorce_Math + pTemp->Sorce_English) / (float)3.0;pTemp->iRank = 0;pTemp->pNext = NULL;if (!pHead){pHead = pTail = pTemp;}else {pTail->pNext = pTemp;pTail = pTemp;}}}void Add(Student* pHead){Student* pCur, * pTail, * pTemp;int iNum, iFlag;if (pHead == NULL){printf("\n没有学生记录,请先创建学生记录!\n");return;}pCur = pHead;while (pCur->pNext != NULL){pCur = pCur->pNext;}pTail = pCur;while (1){while (1){iNum = CheakNum("请输入学生学号:");if (iNum == 0){printf("输入结束!\n");Show(pHead);return;}iFlag = 0;pCur = pHead;while (pCur != NULL){if (pCur->S_Number == iNum){iFlag = 1;break;}pCur = pCur->pNext;}if (iFlag == 1){printf("学号输入与他人重复,请重新输入!\n");continue;}elsebreak;}pTemp = (Student*)malloc(sizeof(Student));if (pTemp == NULL){printf("内存申请失败!");return NULL;}pTemp->S_Number = iNum;printf("请输入姓名:");char c;while ((c = getchar()) != EOF && c != '\n');scanf("%s", &pTemp->name);getchar();pTemp->Sorce_Chinese = CheakScore("请输入语文成绩(0~100):");pTemp->Sorce_Math = CheakScore("请输入数学成绩(0~100):");pTemp->Sorce_English = CheakScore("请输入英语成绩(0~100):");pTemp->avg = (pTemp->Sorce_Chinese + pTemp->Sorce_Math + pTemp->Sorce_English) / (float)3.0;pTemp->iRank = 0;pTemp->pNext = NULL;pTail->pNext = pTemp;pTail = pTemp;}}void Show(Student* pHead){Student* pCur = pHead;int i = 0;if (pCur == NULL){printf("\n没有学生记录,请先创建学生记录!\n");}else{ShowHead(1);while (pCur != NULL){printf("\t| %06d |%10s|%6.2f |%6.2f |%6.2f |%6.2f|\n", pCur->S_Number, pCur->name, pCur->Sorce_Chinese, pCur->Sorce_Math, pCur->Sorce_English, pCur->avg);Print('-', 80, 1);pCur = pCur->pNext;}}printf("\n");system("pause");}void Sreach(Student* pHead){Student* pCur = pHead;int iItem, iNum = 0;char _name[20] = { '\0' };if (pCur == NULL){printf("\n没有学生记录,请先创建学生记录!\n");return;}printf("\n请选择查找方式:\t1.按学号查找\t2.按姓名查找:");scanf("%d", &iItem);getchar();while (iItem > 2 || iItem S_Number == iNum){ShowHead(1);printf("\t| %06d |%10s|%6.2f |%6.2f |%6.2f |%6.2f|\n", pCur->S_Number, pCur->name, pCur->Sorce_Chinese, pCur->Sorce_Math, pCur->Sorce_English, pCur->avg);Print('-', 80, 1);return;}pCur = pCur->pNext;}if (pCur == NULL){printf("\n数据表中没有该学生!\n");}break;case 2:printf("请输入要查找的姓名:");scanf("%s", _name);getchar();while (pCur != NULL){if (strcmp(pCur->name, _name) == 0){ShowHead(1);printf("\t| %06d |%10s|%6.2f |%6.2f |%6.2f |%6.2f|\n", pCur->S_Number, pCur->name, pCur->Sorce_Chinese, pCur->Sorce_Math, pCur->Sorce_English, pCur->avg);Print('-', 80, 1);return;}pCur = pCur->pNext;}if (pCur == NULL){printf("\n数据表中没有该学生!\n");}break;}return;}void Modify(Student* pHead){int iItem, iNum = 0;char _name[20] = { '\0' };Student* pCur = pHead;if (pCur == NULL){printf("\n数据表为空,请先创建数据表!\n");return;}printf("\n请选择查找方式:\t1.按学号查找\t2.按姓名查找:");scanf("%d", &iItem);getchar();while (iItem > 2 || iItem S_Number == iNum){printf("\n原数据为:\n");ShowHead(1);printf("\t| %06d |%10s|%6.2f |%6.2f |%6.2f |%6.2f|\n", pCur->S_Number, pCur->name, pCur->Sorce_Chinese, pCur->Sorce_Math, pCur->Sorce_English, pCur->avg);Print('-', 80, 1);printf("输入需要更改的学生信息:\n");iNum = CheakNum("请输入学生学号:");pCur->S_Number = iNum;printf("请输入姓名:");scanf("%s", pCur->name);getchar();pCur->Sorce_Chinese = CheakScore("请输入语文成绩(0~100):");pCur->Sorce_Math = CheakScore("请输入数学成绩(0~100):");pCur->Sorce_English = CheakScore("请输入英语成绩(0~100):");pCur->avg = (pCur->Sorce_Chinese + pCur->Sorce_Math + pCur->Sorce_English) / (float)3.0;pCur->iRank = 0;return;}pCur = pCur->pNext;}if (pCur == NULL){printf("\n数据表中没有该学生!\n");}break;case 2:printf("请输入要查找的姓名:");scanf("%s", _name);getchar();while (pCur != NULL){if (strcmp(pCur->name, _name) == 0){ShowHead(1);printf("\t| %06d |%10s|%6.2f |%6.2f |%6.2f |%6.2f|\n", pCur->S_Number, pCur->name, pCur->Sorce_Chinese, pCur->Sorce_Math, pCur->Sorce_English, pCur->avg);Print('-', 80, 1);printf("输入需要更改的学生信息:\n");iNum = CheakNum("请输入学生学号:");pCur->S_Number = iNum;printf("请输入姓名:");scanf("%s", pCur->name);getchar();pCur->Sorce_Chinese = CheakScore("请输入语文成绩(0~100):");pCur->Sorce_Math = CheakScore("请输入数学成绩(0~100):");pCur->Sorce_English = CheakScore("请输入英语成绩(0~100):");pCur->avg = (pCur->Sorce_Chinese + pCur->Sorce_Math + pCur->Sorce_English) / (float)3.0;pCur->iRank = 0;return;}pCur = pCur->pNext;}if (pCur == NULL){printf("\n数据表中没有该学生!\n");}break;}return;}Student* Delete(Student* pHead){Student* pCur = pHead, * pTemp = NULL, * prev = pHead;int iItem, iNum = 0;char _name[20] = { '\0' };if (pCur == NULL){printf("\n数据表为空,请先创建数据表!\n");return NULL;}printf("\n请选择查找方式:\t1.按学号查找\t2.按姓名查找:");scanf("%d", &iItem);getchar();while (iItem > 2 || iItem S_Number == iNum){printf("\n要删除的信息:\n");ShowHead(1);printf("\t| %06d |%10s|%6.2f |%6.2f |%6.2f |%6.2f|\n", pCur->S_Number, pCur->name, pCur->Sorce_Chinese, pCur->Sorce_Math, pCur->Sorce_English, pCur->avg);Print('-', 80, 1);if (pCur == pHead){pHead = pHead->pNext;}else{prev->pNext = pCur->pNext;}free(pCur);return pHead;}prev = pCur;pCur = pCur->pNext;}if (pCur == NULL){printf("\n数据表中没有该学生!\n");}break;case 2:printf("请输入要查找的姓名:");scanf("%s", _name);getchar();while (pCur != NULL){if (strcmp(pCur->name, _name) == 0){if (pCur->S_Number == iNum){printf("\n要删除的信息:\n");ShowHead(1);printf("\t| %06d |%10s|%6.2f |%6.2f |%6.2f |%6.2f|\n", pCur->S_Number, pCur->name, pCur->Sorce_Chinese, pCur->Sorce_Math, pCur->Sorce_English, pCur->avg);Print('-', 80, 1);if (pCur == pHead){pHead = pHead->pNext;}else{prev->pNext = pCur->pNext;}free(pCur);return pHead;}prev = pCur;pCur = pCur->pNext;}pCur = pCur->pNext;}if (pCur == NULL){printf("\n数据表中没有该学生!\n");}break;}return pHead;}void ShowSortMenu(){Print('*', 80, 1);printf("1.按学号排序\t\t2.按姓名排序\n");printf("3.按语文成绩排序\t4.按数学成绩排序\n");printf("5.按英语成绩排序\t6.按平均成绩排序\n");Print('*', 80, 1);}void Sort(Student* pHead){Student* pCur = pHead, * pTemp = NULL;int i, j, k, iItem = 0, iCount = 0;if (pCur == NULL){printf("\n没有学生记录!\n");return;}do {iCount++;pCur = pCur->pNext;} while (pCur != NULL);pTemp = (Student*)malloc(iCount * sizeof(Student));pCur = pHead;for (i = 0; i S_Number;strcpy(pTemp[i].name, pCur->name);pTemp[i].Sorce_Chinese = pCur->Sorce_Chinese;pTemp[i].Sorce_Math = pCur->Sorce_Math;pTemp[i].Sorce_English = pCur->Sorce_English;pTemp[i].avg = pCur->avg;pCur = pCur->pNext;}ShowSortMenu();printf("请选择排序方式:");scanf("%d", &iItem);getchar();while (iItem > 6 || iItem < 0){char c;while ((c = getchar()) != EOF && c != '\n');printf("输入有误,请重新输入:");scanf("%d", &iItem);getchar();}for (i = 0; i < iCount - 1; i++){for (j = 0; j  pTemp[j + 1].S_Number){SwapStu(pTemp + j, pTemp + j + 1);}break;case 2:if (strcmp(pTemp[j].name, pTemp[j + 1].name) > 1){SwapStu(pTemp + j, pTemp + j + 1);}break;case 3:if (pTemp[j].Sorce_Chinese > pTemp[j + 1].Sorce_Chinese){SwapStu(pTemp + j, pTemp + j + 1);}break;case 4:if (pTemp[j].Sorce_Math > pTemp[j + 1].Sorce_Math){SwapStu(pTemp + j, pTemp + j + 1);}break;case 5:if (pTemp[j].Sorce_English > pTemp[j + 1].Sorce_English){SwapStu(pTemp + j, pTemp + j + 1);}break;case 6:if (pTemp[j].avg > pTemp[j + 1].avg){SwapStu(pTemp + j, pTemp + j + 1);}break;}}}ShowHead(2);for (int k = 0; k < iCount; k++){pTemp[k].iRank = k + 1;printf("\t| %06d |%10s|%6.2f |%6.2f |%6.2f |%6.2f|%5d |\n", pTemp[k].S_Number, pTemp[k].name, pTemp[k].Sorce_Chinese, pTemp[k].Sorce_Math, pTemp[k].Sorce_English, pTemp[k].avg, pTemp[k].iRank);Print('-', 80, 1);}pCur = pHead;for (i = 0; i S_Number = pTemp[i].S_Number;strcpy(pCur->name, pTemp[i].name);pCur->Sorce_Chinese = pTemp[i].Sorce_Chinese;pCur->Sorce_English = pTemp[i].Sorce_English;pCur->Sorce_Math = pTemp[i].Sorce_Math;pCur->avg = pTemp[i].avg;pCur = pCur->pNext;}}void Statistics(Student* pHead){int iCount = 0;int Pass[3] = { 0 };float sMax[3] = { 0.0 }, sMin[3] = { 0.0 }, sAvg[3] = { 0.0 }, sSum[3] = { 0.0 };float iMaxA, iMinA;//记录最高、最低平均分Student* pCur = pHead;if (pCur == NULL){printf("\n没有学生记录,请先创建学生记录!\n");return;}iMaxA = iMinA = pCur->avg;sMax[0] = sMin[0] = pCur->Sorce_Chinese;//0位置:放语文成绩记录sMax[1] = sMin[1] = pCur->Sorce_Math;sMax[2] = sMin[2] = pCur->Sorce_English;while (pCur != NULL){float C = pCur->Sorce_Chinese, M = pCur->Sorce_Math, E = pCur->Sorce_English, A = pCur->avg;iCount++;sSum[0] += C;sSum[1] += M;sSum[2] += E;if (C >= 60.0){Pass[0]++;}if (M >= 60){Pass[1]++;}if (E >= 60){Pass[2]++;}if (iMaxA  A){iMinA = A;}if (sMax[0] < C){sMax[0] = C;}if (sMax[1] < M){sMax[1] = M;}if (sMax[2]  C){sMin[0] = C;}if (sMin[1] > M){sMin[1] = M;}if (sMin[2] > E){sMin[2] = E;}pCur = pCur->pNext;}sAvg[0] = sSum[0] / iCount;sAvg[1] = sSum[1] / iCount;sAvg[2] = sSum[2] / iCount;printf("\n记录的学生总人数为:%d\n", iCount);Print('=', 32, 0);printf("语文考试成绩分析");Print('=', 32, 1);printf("通过语文考试人数:\t%d\n", Pass[0]);printf("没有通过语文考试人数:\t%d\n", iCount - Pass[0]);printf("语文平均分:\t\t%0.2f\n", sAvg[0]);printf("语文最高分:\t\t%0.2f\n", sMax[0]);printf("语文最低分:\t\t%0.2f\n\n", sMin[0]);Print('=', 32, 0);printf("数学考试成绩分析");Print('=', 32, 1);printf("通过数学考试人数:\t%d\n", Pass[1]);printf("没有通过数学考试人数:\t%d\n", iCount - Pass[1]);printf("数学平均分:\t\t%0.2f\n", sAvg[1]);printf("数学最高分:\t\t%0.2f\n", sMax[1]);printf("数学最低分:\t\t%0.2f\n\n", sMin[1]);Print('=', 32, 0);printf("英语考试成绩分析");Print('=', 32, 1);printf("通过英语考试人数:\t%d\n", Pass[2]);printf("没有通过英语考试人数:\t%d\n", iCount - Pass[2]);printf("英语平均分:\t\t%0.2f\n", sAvg[2]);printf("英语最高分:\t\t%0.2f\n", sMax[2]);printf("英语最低分:\t\t%0.2f\n\n", sMin[2]);Print('=', 32, 0);printf("其他考试成绩分析");Print('=', 32, 1);printf("\n三科总的平均分:%0.2f\n", sAvg[0] + sAvg[1] + sAvg[2]);printf("三科当中最高平均分:%0.2f\n", iMaxA);printf("三科当中最低平均分:%0.2f\n", iMinA);Print('=', 80, 1);system("pause");}Student* Read(){FILE* fp;Student* pHead = NULL, * pTemp = NULL, * pCur = NULL;char FileName[30] = { '\0' };char c;while ((c = getchar()) != EOF && c != '\n');printf("请输入成绩文件表名:");gets(FileName);if ((fp = fopen(FileName, "r")) == NULL){printf("\n文件打开失败!请检查文件名!\n");exit(0);}pTemp = (Student*)malloc(sizeof(Student));while (fread(pTemp, sizeof(Student), 1, fp)){if (!pHead){pHead = pCur = pTemp;}else{pCur->pNext = pTemp;pCur = pTemp;}pTemp = (Student*)malloc(sizeof(Student));}fclose(fp);Show(pHead);return pHead;}void Save(Student* pHead){int iItem;printf("请选择保存格式:\t1.二进制文件\t2.文本文件\n");printf("请输入:");scanf("%d", &iItem);getchar();while (iItem > 2 || iItem pNext;iCount++;}printf("\n");Print('=', 34, 0);printf("保存数据结束");Print('=', 34, 1);printf("保存文件的数据数目为:%d\n", iCount);fclose(fp);}else {FILE* fp;Student* pCur = pHead;int iCount = 0;char FileName[30] = { '\0' };if (pCur == NULL){printf("\n没有学生记录!\n");return;}printf("\n请输入文件名:");gets(FileName);if ((fp = fopen(FileName, "w")) == NULL){printf("创建文件失败!\n");getchar();exit(1);}fprintf(fp, "学号\t姓名\t语文\t数学\t英语\t平均分\n");while (pCur){fprintf(fp, "%d\t%s\t%.2f\t%.2f\t%0.2f\t%0.2f\n", pCur->S_Number, pCur->name, pCur->Sorce_Chinese, pCur->Sorce_Math, pCur->Sorce_English, pCur->avg);pCur = pCur->pNext;iCount++;}printf("\n");Print('=', 34, 0);printf("保存数据结束");Print('=', 34, 1);printf("保存文件的数据数目为:%d\n", iCount);fclose(fp);}}void ShowHead(int iType){printf("\n\t\t\t\t学生成绩管理系统\n\n");Print('-', 80, 1);if (iType == 1){printf("\t| number | name |Chinese| Math|English|averge|\n");}else if (iType == 2){printf("\t| number | name |Chinese| Math|English|averge|rank|\n");}Print('-', 80, 1);}

Student.h

#pragma once#include#include#include #include #include"Student.h"typedef struct Student {char name[20];//姓名int S_Number;//学号float Sorce_Chinese;float Sorce_Math;float Sorce_English;float avg;//平均分int iRank;//排名struct Student* pNext;}Student;void showMainMenu();//打印主界面,显示功能选项Student* Create();//创建学生记录,返回学生结构体类型的指针void Add(Student* pHead);//向已有的数据表中添加数据void Show(Student* pHead);//显示数据表中的所有信息void Sreach(Student* pHead);//在数据表中搜索信息,找到显示该学生信息,没有找到则给出提示void Modify(Student* pHead);//在数据表中搜索信息,找到后修改信息,没有找到则给出提示Student* Delete(Student* pHead);//删除一个学生记录,先查找,若无则给出提示参数:一个已有的链表指针void Sort(); //按照某个字段来排序void Statistics();//统计数据表中的信息,分析各科成绩情况Student* Read();//从文件读取信息void Save();//保存数据表到本地,可以二进制保存或文本格式保存int CheakNum(char* pcNotice);//检查学号输入是否正确float CheakScore(char* pcNotice);//检查成绩输入是否正确void ShowHead(int iType);//打印一段表头void ShowSortMenu();//显示排序功能选项void modeset(int w, int h);//初始化窗口大小

五、程序测试

5.1 测试数据说明

学号 姓名 语文成绩 数学成绩 英语成绩

5.2 输出结果说明

学号 姓名 语文成绩 数学成绩 英语成绩 平均成绩

学号 姓名 语文成绩 数学成绩 英语成绩 平均成绩 排名

目录界面

六、小结与心得

经历了长达一周的C语言实训,我感觉收获满满,之前从没有像这次系统的设计一个管理系统。通过这次实训,我进一步熟悉了C语言的语法,以及数据结构,动态内存,链表等知识。本次收获最大的地方是学会了通过文件操作,来读取、保存文件以及文件的格式。

最后感谢老师!老师辛苦了。

七、参考文献

[1] 严蔚敏 吴伟民.数据结构(C语言版).清华大学出版社

[2] 许真珍 蒋光远 田琳琳.C语言课程设计指导教程.清华大学出版社