1.功能需求
某班有最多不超过30人(具体人数由键盘输人)参加期末考试,最多不超过6门(具体门数由键盘输入)。请使用结构体数组、排序查找算法以及模块化程序设计方法编程实现如下菜单驱动的学生成绩管理系统:
(1)输入每个学生的学号、姓名和若干门课程考试成绩;
(2)计算每门课程的总分和平均分;
(3)计算每个学生的总分和平均分;
(4)按每个学生的总分由高到低排出名次表;
(5)按每个学生的总分由低到高排出名次表;
(6)按学号由小到大排出成绩表;
(7)按姓名的字典顺序排出成绩表;
(8)按学号查询学生排名及其考试成绩;
(9)按姓名查询学生排名及其考试成绩;
(10)按优秀(90~100)、良好(80~89)、中等(70~79)、及格(60~69)、不及格(0~59)5个类别,对每门课程分别统计每个类别的人数以及所占的百分比;
(11)输出每个学生的学号、姓名、各科考试成绩,以及总分和平均分;
(12)将每个学生的记录信息写入文件;
(13)从文件中读出每个学生的记录信息并显示;
以下为选做功能:
(14)向文件中追加1条记录;
(15)删除文件中指定学号的记录;
(16)修改文件中的某个学生的某门功课的成绩。
2.数据需求
每条记录包含学号(长整型)、姓名(字符串)、多门课程的成绩(浮点型)、总成绩(浮点型)、平均成绩(浮点型)。
数据存储于文件StudentRecord.txt中,格式为每行一条记录;文件的第一行数据为学生人数和课程门数。
3.性能需求
系统响应快速,支持至少100条记录的高效处理。
界面友好,操作直观,提供菜单驱动交互。
三、系统设计
1.总体设计
模块划分:
系统采用模块化设计:每个功能模块封装为独立函数;全局数据通过结构体数组统一管理。
主菜单模块:提供功能入口,循环调用各子模块。
具体菜单要求如下:
1.Input record
2.Calculate total and average score of every course
3.Calculate total and average scored of every student
4.Sort in descending order by total score of every student
5.Sort in ascending order by total score of every student
6.Sort in ascending order by number
7.Sort in dictionary order by name
8.Search by number
9.Search by name
10.Statistic analysis for every course
11.List record
12.Write to a file
13.Read from a file
0.Exit
Please enter your choice:
数据输入模块:实现学生信息由键盘录入与验证。
数据处理模块:对结构体数组stu进行按条件查询、排序。
文件操作模块:实现对文件中的数据进行读写、增删改等操作。2.数据结构设计
定义结构体Student:
typedef struct Student {
long num; // 学号
char name[MAX_LEN]; // 姓名
float score[COURSE_NUM]; // 多门课程的成绩
float sum; //每个学生的总分
float aver; // 平均成绩
}STU;
3.算法设计
排序算法:选择排序实现按平均分排序。
查询算法:线性查找实现按学号/姓名查询。
四、系统实现
1.主函数流程
int main(void)
{
char ch;
int n = 0,m = 0;
STU stu[STU_NUM];
printf("Input student number(n<%d):",STU_NUM);
scanf("%d",&n);
printf("Input course number(m<=%d):",COURSE_NUM);
scanf("%d",&m);
while(1) {
ch = Menu(); //显示菜单,并读取用户输入
switch(ch) {
case 1 : ReadScore(stu,n,m); break;
case 2: AverSumofEveryCourse(stu,n,m); break;
case 3: AverSumofEveryStudent(stu,n,m); break;
case 4: SortbyScore(stu,n,m,Descending);
printf("\nSort in descending order by score:\n");
PrintScore(stu,n,m);
break;
case 5: SortbyScore(stu,n,m, Ascending);
printf("\nSort in ascending order by score:\n");
PrintScore(stu,n,m);
break;
case 6: AsSortbyNum(stu,n,m);
printf("\nsort in ascending order by number:\n");
PrintScore(stu,n,m);
break;
case 7: SortbyName(stu,n,m);
printf("\nSort in dictionary order by name:\n");
PrintScore(stu,n,m);
break;
case 8: SearchbyNum(stu,n,m);
break;
case 9: SearchbyName(stu,n,m);
break;
case 10:StatisticAnalysis(stu,n,m);
break;
case 11:PrintScore(stu,n,m);
break;
case 12:WritetoFile(stu,n,m);
break;
case 13:ReadfromFile(stu,&n,&m);
break;
case 0:printf("End of program!");
exit(0);
default:printf("Input error!");
}
}
return 0;
}
2.各功能函数实现
(1)输入每个学生的学号、姓名和若干门课程考试成绩;
(2)计算每门课程的总分和平均分;
(3)计算每个学生的总分和平均分;
(4)按每个学生的总分由高到低排出名次表;
//按选择法将结构体数组stu的元素按总分升(降)序排序
void SortbyScore(STU stu[],int n,int m,int (*compare)(float a,float b))
{
int i,j,k,t;
for(i=0;i<n-1;i++)
{
k=i;
for(j=i+1;j<n;j++)
{
if((*compare)(stu[j].sum,stu[k].sum)) k=j;
}
if(k!=i)
{
//说明:可整体交换两个结构体数组元素,也可以数组元素各成员逐一交换
}
}
}
//使数据按升序排序
int Ascending(float a,float b)
{
return a<b; //这样比较决定了按升序排序,如果a<b, 则交换
}
//使数据按降序排序
int Descending(float a,float b)
{
return a>b; //这样比较决定了按降序排序,如果a>b、则交换
}
(5)按每个学生的总分由低到高排出名次表;
(6)按学号由小到大排出成绩表;
(7)按姓名的字典顺序排出成绩表;
(8)按学号查询学生排名及其考试成绩;
(9)按姓名查询学生排名及其考试成绩;
(10)按优秀(90~100)、良好(80~89)、中等(70~79)、及格(60~69)、不及格(0~59)5个类别,对每门课程分别统计每个类别的人数以及所占的百分比;
(11)输出每个学生的学号、姓名、各科考试成绩,以及总分和平均分;
(12)将每个学生的记录信息写入文件;
(13)从文件中读出每个学生的记录信息并显示;
五、测试与调试
1.测试用例
正常输入:输入有效学号、姓名及成绩,验证排序与查询功能。
异常输入:输入非数字成绩,验证错误提示机制。
说明:
1)可以使用多张测试用例表,对不同的功能模块进行测试。在测试用例表中给出正常与异常的测试数据进行功能测试。
2)也可以给出正常或异常测试的运行结果截图
2.调试问题
文件读写错误:文件路径错误→统一使用相对路径并检查权限。
最新发布