课程设计
- 格式:docx
- 大小:156.97 KB
- 文档页数:18
分类号10编号8华北水利水电大学North China Institute of Water Conservancy and HydroelectricPower课程设计题目学生成绩管理系统院系信工学院专业计算机科学与技术姓名赵敏郭海雅高婷婷学号201522122 ,24,25指导教师杨彬2016年7月1日学生成绩管理系统一:题目的内容及要求现有学生成绩信息文件1(1.txt),内容如下:姓名学号语文数学英语张明明01 67 78 82李成友02 78 91 88张辉灿03 68 82 56王露04 56 45 77陈东明05 67 38 47…………学生成绩信息文件2(2.txt),内容如下:姓名学号语文数学英语陈果31 57 68 82李华明32 88 90 68张明东33 48 42 56李明国34 50 45 87陈道亮35 47 58 77…………试编写一个管理系统,要求如下:1) 要求使用链表或数组等实现上述要求2) 实现对两个文件数据进行合并,生成新文件3.txt3) 可实现学生成绩信息的输入、修改、删除功能4) 抽取出三科成绩中有补考的学生并保存在一个新文件4.txt5)对合并后的文件3.txt中的数据按总分降序排序(至少采用两种排序方法实现)6)输入一个学生姓名后,能查找到此学生的信息并输出结果(至少采用两种查找方法实现)7)统计输出各门课程的平均分,最高分、最低分8)统计各门课程优秀、良好、中等、及格、不及格的人数及百分比二:小组成员分工及本人承担的任务赵敏:4) 抽取出三科成绩中有补考的学生并保存在一个新文件4.txt7)统计输出各门课程的平均分,最高分、最低分8)统计各门课程优秀、良好、中等、及格、不及格的人数及百分比郭海雅:1) 要求使用链表或数组等实现上述要求2) 实现对两个文件数据进行合并,生成新文件3.txt6)输入一个学生姓名后,能查找到此学生的信息并输出结果(至少采用两种查找方法实现)高婷婷:3) 可实现学生成绩信息的输入、修改、删除功能5)对合并后的文件3.txt中的数据按总分降序排序(至少采用两种排序方法实现)三:问题的描述和分析1.1问题的描述随着社会的发展和经济时代的到来,管理信息系统在各行各业都越来越重要,特别是教育事业。
在经济发达的国家,许多教育机构(如公办、私立、培训机构等),都投入了大量的资金开发MIS系统,以求在将来激烈的竞争中立于不败之地。
在我国,民办教育是新兴的一个行业,是随着改革开放和市场经济的发展根据中国特有的国情发展起来的,特别是中国民办教育促进法的出台,从一定的程度上规范和促进了中国民办教育的发展,这是一个很有发展前途的新兴产业,但是同发达国家相比,我国的民办教育行业的信息技术的应用程度还很低,只有在大城市中发展较早、规模较大的民办院校中才使用计算机进行大规模操作,从各方面提高工作效率,取得良好的社会和经济效益,而一些新兴的、规模较小的民办机构还没有全部具备这种功能。
因此可见,随着我国民办教育的迅速发展,信息技术在其上的应用会更加地广泛和深入。
1.2现有系统存在问题的分析有的学校根本就没有系统,还是手工操作计算机日新月异的发展,但是有的领导只见眼前利益,不关心,甚至不敢尝试新兴的事物。
手工操作还十分落后,效率极低,成本很大,以后的社会是信息的社会,信息只有快,准,精才能发挥其价值。
所以机器代替人力是必然的历史发展趋势,只有领导的重视和支持才能从人工操作改为计算机的自动化系统。
人工操作必将被计算机代替。
有些学校虽使用了计算机,甚至管理系统,但是仍然存在很多问题,问题一日不解决,效率就一日提不上去。
还有,有的系统很不完善到处是漏洞,可以说是千疮百孔,这样极不完善的系统能有保障吗?所以制作一个完善的学生管理系统是必不可少的。
四、数据结构的设计struct person{char name[20];longnum;float math;float English;floatchinese;float average;float sum;}student;五:设计程序1:流程图首先,分析题目要求划分实现模块,定义基本数据类型,诸如结构体、数组等,其中采用数组实现顺序存储方式;其次,针对上述的基本操作实现具体需要进行的操作,具体实现每个环节需要进行的基本操作,即具体编写每个小函数实现功能;最后,编写主函数对每个实现进行按需调用,实现操作。
3:选择原因:在查找和排序时,使用非常便捷;4:5:详细设计(包括数据结构的类型定义,每个操作的算法描述);六:源代码#include <iostream>#include <fstream>#include <string>#include <iomanip>using namespace std;string str[5] ; //定义一个str字符串来吸收文件2.txt中重复的标题intaNum=0; //使用全局变量定义学生的人数structadent //构建结构体{char name[10]; //姓名int id;intchinese;int math;intenglish;int sum;}a[50],temp;//实现对文件1.txt和文件2.txt数据的合并,生成文件3.txtvoid Merge(){char* f1 = "d:\\1.txt";char* f2 = "d:\\2.txt";char* f3 = "d:\\3.txt";ifstream inFile1( f1 ); //从磁盘读取文件1.txtifstream inFile2( f2 ); //从磁盘读取文件2.txtofstreamoutFile( f3 ); //写入信息到文件3.xtxoutFile<< inFile1.rdbuf(); //把文件1.txt中的数据写入到outfilefor(inti=0;!inFile2.eof()==true;i++) //遍历文件2.txt的所有数据{stringstr;getline(inFile2,str); //读取第一行信息放到str中if(i==0)continue; //跳过第一行outFile<<str<<endl; //把后面的信息放入到文件3.txt}inFile1.close(); //关闭文件f1inFile2.close();outFile.close();ifstream f ( f3 );cout<<"**文件已生成,合并后数据如下**"<<endl;cout<<f.rdbuf(); //输出文件3.txt};//把文件3.txt中的数据读出到结构体中,便于对数据的操作voidFillStruct(adent *p){inti=aNum, j=0; //这里让i = aNum,假如先添加数据,后合并,则结构体下标中人数i不是从0开始计,而是从先输入的数据的个数aNum开始的ifstreaminfile("D:\\3.txt",ios::in); //以读的方式打开文件3.txtif(!infile) //测试是否成功打开{cerr<<"open error!"<<endl;exit(1);}while(!infile.eof()) //遍历infile,只把数据写入进去,过滤掉第一行的头标题{while(j<5) //用一个str数组把文件3.txt中的头标题给吸收进去{infile>>str[j];j++;}//把磁盘中的文件读出来写入到结构体中infile>> p[i].name >> p[i].id >> p[i].chinese>> p[i].math >> p[i].english;aNum++;i++;}aNum=aNum-1; //数据读完后因光标移到下一行,等于是多读了一行,所以真实的人数要比计数减一(不知道理解的对不?)infile.close(); //关闭文件};//抽取出三科成绩中有补考的学生并保存在一个新文件4.txtintFailList(adent *p){/*如果先开始进行的操作不是合并或者添加数据,那么其他的操作将无法进行,因为结构体中没有学生数据,返回主菜单*/if(aNum==0){cout<<"请先合并或者输入数据"<<endl;return 0;}ofstream in;in.open("d:\\4.txt",ios::trunc); //如不空则清空in<<"补考名单"<<endl; //用插入器(<<)向文件输出;用析取器(>>)从文件输入for(inti=0;i<aNum;i++){if(p[i].chinese<60||p[i].english<60||p[i].math<60){in<<p[i].name<<"\t";}}};void sum(adent *p) //求总和{for(inti=0;i<aNum;i++){p[i].sum=p[i].chinese+p[i].english+p[i].math;}}void traversal(adent *p) //遍历输出学生数据{cout<<"姓名"<<'\t'<<"学号"<<'\t'<<"语文"<<'\t'<<"数学"<<'\t'<<"英语"<<'\t'<<"总分"<<endl;for(inti=0;i<aNum;i++){cout<<p[i].name<<'\t'<<p[i].id<<'\t'<<p[i].chinese<<'\t'<<p[i].math<<'\t'<<p[i].english<<'\t'< <p[i].sum<<endl;}}//对学生总分按照从高到低的顺序排列int Sort(adent *p){if(aNum==0){cout<<"请先合并或者输入数据"<<endl;return 3;}sum(p);int flag=0; //设标识位do{cout<<"请输入排序方式,输入“1”冒泡排序, 输入“2”直接插入排序"<<endl;cin>>flag;if(flag==1)//冒泡{for(inti=0;i<aNum-1;++i) //外层循环{for(int k=i;k<aNum-1;++k) //内层循环{if(p[k].sum <p[k+1].sum) //按照从大到小的顺序进行排列{temp = p[k];p[k] = p[k+1];p[k+1] = temp;}}}traversal(p); //输出排序后的结果return 1;}if(flag==2)//直接插入{for(inti=1;i<aNum;i++){temp=p[i]; //将要比较的关键数赋给哨兵tempint j=i-1;while(j>=0 &&temp.sum>p[j].sum) //直到越界或者把哨兵的值和j的值进行比较{p[j+1]=p[j]; //如果J的值比哨兵的值小,则把j的值向后移动j--; //j向前移,循环进行比较}p[j+1]=temp; //直到找到temp的值比j的值小,就把哨兵里的值放在j得后面}traversal(p);return 1;}if(flag!=1 && flag!=2){cout<<"输入错误,请重新输入";flag=3;}}while(flag=3);}//输入一个学生姓名后,能查找到此学生的信息并输出结果int Select(adent *p){if(aNum==0){cout<<"请先合并或者输入数据"<<endl;return 3;}inti=0;cout<<"请输入查询的姓名:";charsname[10];cin>>sname;while(i<aNum){if(strcmp(sname,p[i].name)==0) //通过字符串的比较来搜索要查找的姓名{cout<<"姓名"<<'\t'<<"学号"<<'\t'<<"语文"<<'\t'<<"数学"<<'\t'<<"英语"<<endl;cout<<p[i].name<<'\t'<<p[i].id<<'\t'<<p[i].chinese<<'\t'<<p[i].math<<'\t'<<p[i].english<<endl ;return 1;}else{i++;if(i==aNum){cout<<"无此学生返回主菜单"<<endl;return 0;}}}}//////////////////////////////////通过学号查找int search(adent *p){if(aNum==0){cout<<"请先合并或者输入数据"<<endl;return 3;}inti=0;cout<<"请输入查询的学号:";int id;cin>>id;int low=0,high=aNum-1,mid;if(id<low||id>high){cout<<"无此学生返回主菜单"<<endl;return 0;}while(low<=high){mid=(low+high)/2;if(p[i].id==id){cout<<"姓名"<<'\t'<<"学号"<<'\t'<<"语文"<<'\t'<<"数学"<<'\t'<<"英语"<<endl;cout<<p[i].name<<'\t'<<p[i].id<<'\t'<<p[i].chinese<<'\t'<<p[i].math<<'\t'<<p[i].english<<endl ;return 1;}else if(id<p[i].id)high=mid-1;elselow=mid+1;}}//统计输出各门课程的平均分,最高分、最低分//统计各门课程优秀、良好、中等、及格、不及格的人数及百分比int Statistics(adent *p){ if(aNum==0){cout<<"请先合并或者输入数据"<<endl;return 0;}int flag=0;cout<<"请输入您想进行统计的科目,语文输入“1”,数学输入“2”,英语输入“3”"<<endl;cin>>flag;if(flag==1){float tempmax=0,tempmin=100,tempsum=0,tempgood=0,tempnormal=0,tempbad=0;for(inti=0;i<aNum;i++){if(p[i].chinese>tempmax)tempmax=p[i].chinese; //找到最高分if(p[i].chinese<tempmin)tempmin=p[i].chinese; //找到最低分if(p[i].chinese>=85)tempgood++; //找到优秀的人数if(p[i].chinese>=60 &&p[i].chinese<85)tempnormal++; //中等的人数if(p[i].chinese<60)tempbad++; //不及格的人数tempsum=tempsum+p[i].chinese; //语文的总分}cout<<"语文成绩平均分为:"<<setprecision(4)<<tempsum/aNum<<'\t'<<"最高分为:"<<tempmax<<'\t'<<"最低分为:"<<tempmin<<endl;cout<<"优秀的人数:"<<tempgood<<" 普通的人数:"<<tempnormal<<" 不及格的人数:"<<tempbad<<endl;cout<<"优秀(大于等于85)百分比为:"<<setprecision(4)<<tempgood/aNum*100<<'\t'<<"中等(60到85之间)百分比为:"<<tempnormal/aNum*100<<'\t'<<"不及格(小于60)百分比为:"<<tempbad/aNum*100<<endl;}if(flag==2){float tempmax=0,tempmin=100,tempsum=0,tempgood=0,tempnormal=0,tempbad=0;for(inti=0;i<aNum;i++){if(p[i].math>tempmax)tempmax=p[i].math;if(p[i].math<tempmin)tempmin=p[i].math;if(p[i].math>=85)tempgood++;if(p[i].math>=60 && p[i].math<85)tempnormal++;if(p[i].math<60)tempbad++;tempsum=tempsum+p[i].math;}cout<<"数学成绩平均分为:"<<setprecision(4)<<tempsum/aNum<<'\t'<<"最高分为:"<<tempmax<<'\t'<<"最低分为:"<<tempmin<<endl;cout<<"优秀的人数:"<<tempgood<<" 普通的人数:"<<tempnormal<<" 不及格的人数:"<<tempbad<<endl;cout<<"优秀(大于等于85)百分比为:"<<setprecision(4)<<tempgood/aNum*100<<'\t'<<"中等(60到85之间)百分比为:"<<tempnormal/aNum*100<<'\t'<<"不及格(小于60)百分比为:"<<tempbad/aNum*100<<endl;}if(flag==3){float tempmax=0,tempmin=100,tempsum=0,tempgood=0,tempnormal=0,tempbad=0;for(inti=0;i<aNum;i++){if(p[i].english>tempmax)tempmax=p[i].english;if(p[i].english<tempmin)tempmin=p[i].english;if(p[i].english>=85)tempgood++;if(p[i].english>=60 &&p[i].english<85)tempnormal++;if(p[i].english<60)tempbad++;tempsum=tempsum+p[i].english;}cout<<"英语成绩平均分为:"<<setprecision(4)<<tempsum/aNum<<'\t'<<"最高分为:"<<tempmax<<'\t'<<"最低分为:"<<tempmin<<endl;cout<<"优秀的人数:"<<tempgood<<" 普通的人数:"<<tempnormal<<" 不及格的人数:"<<tempbad<<endl;cout<<"优秀(大于等于85)百分比为:"<<setprecision(4)<<tempgood/aNum*100<<'\t'<<"中等(60到85之间)百分比为:"<<tempnormal/aNum*100<<'\t'<<"不及格(小于60)百分比为:"<<tempbad/aNum*100<<endl;}};//添加数据voidadda(adent *p){int aid=0,ac=0,am=0,ae=0;char aname[10];cout<<"请输入学号:"<<endl;cin>>aid;p[aNum].id=aid;cout<<"请输入姓名:"<<endl;cin>>aname;strcpy(p[aNum].name,aname);cout<<"请输入语文成绩:"<<endl;cin>>ac;p[aNum].chinese=ac;cout<<"请输入数学成绩:"<<endl;cin>>am;p[aNum].math=am;cout<<"请输入英语成绩:"<<endl;cin>>ae;p[aNum].english=ae;cout<<"录入成功"<<endl;aNum++; //学生人数}//删除数据intdela(adent *p){if(aNum==0){cout<<"请先合并或者输入数据"<<endl;return 3;}inti=0,aid=0;cout<<"请输入要删除学生的学号"<<endl;cin>>aid;while(i<aNum){if(p[i].id==aid) //找到要删除的id{for(int j=i;j<aNum-1;j++)p[i]=p[i+1]; //向前移动一位aNum--; //人数减一cout<<"删除成功"<<endl;return 1;}else{i++;if(i==aNum){cout<<"无此学生返回主菜单"<<endl;return 0;}}}//while}//修改数据intaltera(adent *p){if(aNum==0){cout<<"请先合并或者输入数据"<<endl;return 3;}int aid=0,ac=0,am=0,ae=0,i=0;char aname[10];cout<<"请输入要修改学生的学号"<<endl;cin>>aid;while(i<aNum){if(p[i].id==aid){cout<<"请输入新姓名:"<<endl;cin>>aname;strcpy(p[aNum].name,aname);cout<<"请输入新语文成绩:"<<endl;cin>>ac;p[aNum].chinese=ac;cout<<"请输入新数学成绩:"<<endl;cin>>am;p[aNum].math=am;cout<<"请输入新英语成绩:"<<endl;cin>>ae;p[aNum].english=ae;cout<<"修改成功"<<endl;return 1;}else{i++;if(i==aNum){cout<<"无此学生返回主菜单"<<endl;return 0;}}}//while}//菜单void menu(){cout<<"-------------------------------学生成绩管理系统---------------------------------"<<endl;cout<<" 1:对文件进行合并生成3.txt(在D盘下)"<<endl;cout<<" 2:添加数据"<<endl;cout<<" 3:修改数据"<<endl;cout<<" 4:删除数据"<<endl;cout<<" 5:按姓名查找某一学生成绩"<<endl;cout<<" 6:按学号查找某一学生成绩"<<endl;cout<<" 7:生成需补考学生名单4.txt(在D盘下)"<<endl;cout<<" 8:对学生成绩进行排序"<<endl;cout<<" 9:进行各科成绩的统计(平均分,最高分,最低分,成绩层次分布)"<<endl; cout<<" 10:退出"<<endl;cout<<"--------------------------------------------------------------------------------"<<endl;}//主函数void main(){system("color 79"); //系统颜色int choice;do{menu();cout<<"请输入您需要操作对应阿拉伯数字(1~9)"<<endl;cin>>choice;switch(choice){case 1:Merge();FillStruct(a);break;case 2:adda(a);break;case 3:altera(a);break;case 4:dela(a);break;case 5:Select(a);break;case 6:search(a);break;case 7:FailList(a);break;case 8:Sort(a);break;case 9:Statistics(a);break;case 10:exit(0);break;}//switch}while(1);}七:运行结果及分析(包括测试数据、测试输出的结果、时间复杂度分析、算法的改进设想等)4、生成需补考学生名单4.txt7,8、各科成绩的统计相关算法的讨论、分析,改进设想:在做补考名单的之前,必须先进行合并或添加数据,不然结构体中没有学生数据,所有的操作基本都没办法进行。