一、设计目的
随着信息技术的发展,过去很多由人工处理的复杂事务开始由计算机来完成,学生成绩管理系统利用计算机对学生成绩进行统一的管理,实现完善的学生成绩录人、维护、统计、排序、保存到文件、打开成绩文件等管理工作,从而节约时间,提高教务人员的工作效率。
二、需求分析
本学生成绩管理系统可以实现对众多学生信息的统一管理,其中记录的学生信息包括学生的学号、姓名、语文成绩、数学成绩、英语成绩、三门课程的平均成绩和平均成绩排名。具体功能需求描述如下。
(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<stdio.h>
#include<stdlib.h>
#include<malloc.h>
#include<conio.h>
#include<windows.h>
#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请输入要执行的功能选项<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<stdio.h>
#include<malloc.h>
#include<string.h>
#include <conio.h>
#include <windows.h>
#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 < 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] = { '\0' };
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] = { '\0' };
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] = { '\0' };
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.按学号排序\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 < 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记录的学生总人数为:%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 < 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] = { '\0' };
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("保存文件的数据数目为:%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<stdio.h>
#include<malloc.h>
#include <conio.h>
#include <windows.h>
#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语言课程设计指导教程.清华大学出版社