某班同学(具体人数由键盘输入)参加期末考试,最多不超过6门(具体门数由键盘输入)。使用链表编程成实现如下菜单驱动的学生成绩管理系统。
1.从文件读入每个学生个人信息和成绩信息,可以由键盘输入文件名。读入成功提示读入学生记录的个数,不成功提示相应出错信息。
2.增量式手动录入每个学生的学号(8位数字)、姓名和各科考试成绩。不考虑中文姓名,不考虑重名情况下的处理,学生的学号是唯一的。
3.计算每门课程的总分和平均分;
4.计算每个学生的总分和平均分;
5.按每个学生的总分由高到低排出名次表;
6.按每个学生的总分由低到高排出名次表;
7.按学号由小到大排出成绩表;
8.按姓名的字典顺序排出成绩表;
9.按学号查询学生排名及其考试成绩;
10.按姓名查询学生排名及其考试成绩;需要考虑学生重名的情况。
11.按优秀(100-90)、良好(89-80)、中等(79-70)、及格(69-60)、不及格(59-0)5个类别,对每门课程分别统计每个类别的人数以及所占的百分比;并将计算结果输出到文件,文件名可由键盘输入。
12.输出每个学生的学号、姓名、各科考试成绩、总分和平均分;
13.将每个学生的个人信息和成绩写入文件,可由键盘输入文件名;
要求程序运行后先显示如下菜单,并提示用户输入选项(菜单式循环显示,直到选择0.exit 整个程序退出):
1.Read from a file
2.Append record manually
3.Calculate total and average score of every course
4.Calculate total and average score of every student
5.Sort in descending order by total score of every student
6.Sort in ascending order by total score of every stuednet
7.Sort in ascending order by number
8.Sort in dictionary order by name
9.Search by number
10.Search by name
11.Statistic analysis for every course
12.List record
13.Write to a file
0 . Exit
Please input your choice:
然后根据用户输入的选项进行相应的操作。
界面展示:
下面是代码,代码有点长,好在我都写有详细的注释,请耐心一点:
主函数:
定义两个结构体:
typedef struct _SCORE //储存学生每科学习成绩结构体
{
//各学科成绩:
float maths; //数学
float English; //英语
float Politics; //政治
float Physics; //物理
float computer; //计算机
}SCORE;
typedef struct _STUDENT //储存学生信息的结构体
{
//学生信息_数据域
char stName[20]; //姓名
char StudentId[10]; //学号
int Rank; //总分排名
float TotalScore; //总分数
float Average; //平均分
SCORE Score; //各科成绩
struct _STUDENT* pNext; //_指针域:指向各节点的指针
}STUDENT;
初始化学生信息,并写入磁盘文件中:
STUDENT* InitStudentInfo() //初始化学生信息并写入磁盘
{
STUDENT* pList = NULL; //链表头
int i;
STUDENT* pTemp = (STUDENT*)malloc(sizeof(STUDENT));//创建首节点
if (pTemp == NULL)
{
printf("申请创建首元节点空间失败:\n");
return pTemp;
}
pList = pTemp; //头指针指向首节点
pTemp->pNext = NULL; //首节点指针域赋空值
printf("请输入要录入学生的人数:\n");
scanf("%d", &N);
printf("请输入第1个学生的信息:(姓名栏请输入汉字或英文,学号栏以及分数栏请输入数字)\n");
printf("输入学生姓名:\n"); //第一个学生的信息录入首节点
scanf("%s", pTemp->stName);
printf("输入学生学号:\n");
scanf("%s", pTemp->StudentId);
printf("输入数学分数:\n");
scanf("%f",&pTemp->Score.maths);
printf("输入英语分数:\n");
scanf("%f", &pTemp->Score.English);
printf("输入物理分数:\n");
scanf("%f", &pTemp->Score.Physics);
printf("输入政治分数:\n");
scanf("%f", &pTemp->Score.Politics);
printf("输入计算机分数:\n");
scanf("%f", &pTemp->Score.computer);
pTemp->Rank = 0; //初始化学生名次
pTemp->TotalScore = pTemp->Score.maths + pTemp->Score.English + pTemp->Score.Physics + pTemp->Score.Politics + pTemp->Score.computer;
pTemp->Average = pTemp->TotalScore / 5.0;
printf("------------------\n");
for (i = 2; i <= N; i++) //从第二个节点开始录入
{
//创建一个新节点并初始化
STUDENT* a = (STUDENT*)malloc(sizeof(STUDENT));
if (a == NULL)
{
printf("创建新节点空间失败:\n");
return a;
}
INSPECT:
printf("请输入第%d个学生的信息:(姓名栏请输入汉字或英文,学号栏以及分数栏请输入数字)\n",i); //首节点先初始化
printf("输入学生姓名:\n");
scanf("%s", a->stName);
printf("输入学生学号:\n");
scanf("%s", a->StudentId);
STUDENT* pInspect = pList; //新建一个头指针。用来遍历链表,检查学号是否被录入过
while (pInspect)
{
if (strcmp(pInspect->StudentId,a->StudentId)==0) //检查学号是否存在
{
printf("该学生信息已经录入,请重新输入学生信息:\n");
goto INSPECT;
}
pInspect = pInspect->pNext;
}
printf("输入数学分数:\n");
scanf("%f", &a->Score.maths);
printf("输入英语分数:\n");
scanf("%f", &a->Score.English);
printf("输入物理分数:\n");
scanf("%f", &a->Score.Physics);
printf("输入政治分数:\n");
scanf("%f", &a->Score.Politics);
printf("输入计算机分数:\n");
scanf("%f", &a->Score.computer);
printf("------------------\n");
a->Rank = 0; //初始化学生名次
a->TotalScore = a->Score.maths + a->Score.English + a->Score.Physics + a->Score.Politics + a->Score.computer;
a->Average = a->TotalScore / 5.0;
a->pNext = NULL; //将新节点的指针域置NULL
pTemp->pNext = a; //将pTemp节点与新建立的a节点建立逻辑关系
pTemp = pTemp->pNext; //指针pTemp每次都指向新链表的最后一个节点,其实就是 a节点,这里写pTemp=a也可以
}
system("CLS"); //清除屏幕内容
OutMenu(); //重新在屏幕显示菜单项
WriteToFile(pList);//调用写入文件到磁盘的函数,将链表信息写入文件
return pList;
}
菜单选项函数:
VOID InTab() //从键盘输入菜单选项(数字0-13)
{
printf("**********************************************************************\n");
printf("* 如果您是第一次使用本系统,请首先选择 13 选项卡。对学生信息进行录入 *\n");
printf("**********************************************************************\n");
STUDENT* pList = NULL; //建立链表头指针
int Id = 0;
while (TRUE)
{
Judge:
printf("请选择菜单功能:(0--13)");
scanf("%d", &Id); //键盘输入数字
if (Id < 0 || Id>13) //判断输入的数字是否在规定范围内,不在范围则重新输入
{
printf("您输入的数字有误,");
goto Judge;
}
switch (Id) //使用SWITCH判断输入的数字选项,按照选项来调用功能函数.各项功能见菜单