随着信息技术的发展,过去很多由人工处理的复杂事务开始由计算机来完成,学生成绩管理系统利用计算机对学生成绩进行统一的管理,实现完善的学生成绩录人、维护、统计、排序、保存到文件、打开成绩文件等管理工作,从而节约时间,提高教务人员的工作效率。
二、需求分析本学生成绩管理系统可以实现对众多学生信息的统一管理,其中记录的学生信息包括学生的学号、姓名、语文成绩、数学成绩、英语成绩、三门课程的平均成绩和平均成绩排名。具体功能需求描述如下。
(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.函数之间的调用关系
- 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();
功能:显示排序功能选项
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); Student* pHead = NULL; int iItem; while (1) { showMainMenu(); printf("n请输入要执行的功能选项<0~10>:"); 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("ntttt学生成绩管理系统nn"); Print('*', 80, 1); printf("1.创建记录tt5.更改数据tt9.从文件读取数据n"); printf("2.添加数据tt6.删除数据tt10.保存数据n"); printf("---------tt---------tt---------n"); printf("3.显示数据tt7.数据排序tt0.退出n"); printf("4.查找数据tt8.统计数据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 < 0); return inum; } float CheakScore(char* pcNotice) { float iScore; do { printf(pcNotice); scanf("%f", &iScore); if (iScore > 100 || iScore < 0) { printf("成绩输入有误,请重新输入!"); char c; while ((c = getchar()) != EOF && c != 'n'); } } while (iScore > 100 || iScore < 0); return iScore; } Student* Create() { Student* pHead = NULL, * pTail = NULL, * pTemp, * pCur; int iNum, iFlag; while (1) { while (1) { iNum = CheakNum("请输入学生学号<输入0退出>:"); 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; } else break; } 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("请输入学生学号<输入0退出>:"); 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; } else break; } 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] = { ' ' }; if (pCur == NULL) { printf("n没有学生记录,请先创建学生记录!n"); return; } printf("n请选择查找方式:t1.按学号查找t2.按姓名查找:"); scanf("%d", &iItem); getchar(); while (iItem > 2 || iItem < 1) { char c; while ((c = getchar()) != EOF && c != 'n'); printf("输入有误,请重新输入!n"); scanf("%d", &iItem); } switch (iItem) { case 1: printf("请输入要查找的学号:"); scanf("%d", &iNum); getchar(); while (pCur != NULL) { if (pCur->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] = { ' ' }; Student* pCur = pHead; if (pCur == NULL) { printf("n数据表为空,请先创建数据表!n"); return; } printf("n请选择查找方式:t1.按学号查找t2.按姓名查找:"); scanf("%d", &iItem); getchar(); while (iItem > 2 || iItem < 1) { printf("输入有误,请重新输入!n"); scanf("%d", &iItem); char c; while ((c = getchar()) != EOF && c != 'n'); } switch (iItem) { case 1: printf("请输入要查找的学号:"); scanf("%d", &iNum); getchar(); while (pCur != NULL) { 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); 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] = { ' ' }; if (pCur == NULL) { printf("n数据表为空,请先创建数据表!n"); return NULL; } printf("n请选择查找方式:t1.按学号查找t2.按姓名查找:"); scanf("%d", &iItem); getchar(); while (iItem > 2 || iItem < 1) { char c; while ((c = getchar()) != EOF && c != 'n'); printf("输入有误,请重新输入!n"); scanf("%d", &iItem); } switch (iItem) { case 1: printf("请输入要删除的学号:"); scanf("%d", &iNum); getchar(); while (pCur != NULL) { 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; } 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.按学号排序tt2.按姓名排序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 < iCount; i++) { pTemp[i].S_Number = pCur->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("请选择排序方式<按0返回主页>:"); 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 < iCount - i - 1; j++) { switch (iItem) { case 0: return; case 1: if (pTemp[j].S_Number > 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 < iCount; i++) { pCur->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) { iMaxA = A; } if (iMinA > A) { iMinA = A; } if (sMax[0] < C) { sMax[0] = C; } if (sMax[1] < M) { sMax[1] = M; } if (sMax[2] < E) { sMax[2] = E; } if (sMin[0] > 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记录的学生总人数为:%dn", iCount); Print('=', 32, 0); printf("语文考试成绩分析"); Print('=', 32, 1); printf("通过语文考试人数:t%dn", Pass[0]); printf("没有通过语文考试人数:t%dn", iCount - Pass[0]); printf("语文平均分:tt%0.2fn", sAvg[0]); printf("语文最高分:tt%0.2fn", sMax[0]); printf("语文最低分:tt%0.2fnn", sMin[0]); Print('=', 32, 0); printf("数学考试成绩分析"); Print('=', 32, 1); printf("通过数学考试人数:t%dn", Pass[1]); printf("没有通过数学考试人数:t%dn", iCount - Pass[1]); printf("数学平均分:tt%0.2fn", sAvg[1]); printf("数学最高分:tt%0.2fn", sMax[1]); printf("数学最低分:tt%0.2fnn", sMin[1]); Print('=', 32, 0); printf("英语考试成绩分析"); Print('=', 32, 1); printf("通过英语考试人数:t%dn", Pass[2]); printf("没有通过英语考试人数:t%dn", iCount - Pass[2]); printf("英语平均分:tt%0.2fn", sAvg[2]); printf("英语最高分:tt%0.2fn", sMax[2]); printf("英语最低分:tt%0.2fnn", sMin[2]); Print('=', 32, 0); printf("其他考试成绩分析"); Print('=', 32, 1); printf("n三科总的平均分:%0.2fn", sAvg[0] + sAvg[1] + sAvg[2]); printf("三科当中最高平均分:%0.2fn", iMaxA); printf("三科当中最低平均分:%0.2fn", iMinA); Print('=', 80, 1); system("pause"); } Student* Read() { FILE* fp; Student* pHead = NULL, * pTemp = NULL, * pCur = NULL; char FileName[30] = { ' ' }; 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 < 1) { char c; while ((c = getchar()) != EOF && c != 'n'); printf("输入有误,请重新输入!n"); printf("请输入:"); scanf("%d", &iItem); getchar(); } if (iItem == 1) { FILE* fp; Student* pCur = pHead; int iCount = 0; char FileName[30] = { ' ' }; if (pCur == NULL) { printf("n没有学生记录!n"); return; } printf("n请输入文件名:"); gets(FileName); if ((fp = fopen(FileName, "wb")) == NULL) { printf("创建文件失败!n"); getchar(); exit(1); } while (pCur) { fwrite(pCur, sizeof(Student), 1, fp); pCur = pCur->pNext; iCount++; } printf("n"); Print('=', 34, 0); printf("保存数据结束"); Print('=', 34, 1); printf("保存文件的数据数目为:%dn", iCount); fclose(fp); } else { FILE* fp; Student* pCur = pHead; int iCount = 0; char FileName[30] = { ' ' }; 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, "%dt%st%.2ft%.2ft%0.2ft%0.2fn", 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("保存文件的数据数目为:%dn", iCount); fclose(fp); } } void ShowHead(int iType) { printf("ntttt学生成绩管理系统nn"); 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语言课程设计指导教程.清华大学出版社



