C语言实训报告—学生成绩管理系统(文件实现)
题 目: 学生成绩管理系统 院 系: 专 业: 姓 名: 学 号: 指导教师:
日 期: 2017年9月9日
实训报告
目 录
1 问题定义 ……………………………………………………………………………………1 2 系统设计 ……………………………………………………………………………………1 2.1 总体设计………………………………………………………………………………1 2.2 函数预览………………………………………………………………………………2 3 系统实现 ……………………………………………………………………………………3 3. 1 功能模块………………………………………………………………………………3 3. 2 全部代码………………………………………………………………………………12 4 系统维护 ……………………………………………………………………………………19 4.1 调试和测试……………………………………………………………………………19 5 归纳总结 ……………………………………………………………………………………19 5. 1 开发经验………………………………………………………………………………20 5. 2 实训中遇到的问题及解决方法………………………………………………………20 5. 3 设计中的不足之处……………………………………………………………………20 5. 4 感想和心得体会………………………………………………………………………20 6 参考资料 ……………………………………………………………………………………20
前 言
课程设计环节是应用型本科院校非常重要的一个教学环节,是学完一门课后应用本课知识及以前的知识积累而进行的综合性、开放性的训练。通过课程设计,不仅能够使学生得到系统的技能训练,巩固和加强所学得专业理论知识,而且能够培养学生工程意识、创新能力、团队精神等综合素质,培养学生的设计能力和解决实际问题的能力。
C语言由于其强大的功能,丰富的表达能力,高效的代码,良好的移植性和灵活性,自1972年问世以来,经久不衰,即使现在出现了面向对象的程序设计方法和开发工具,但它仍然是人们学习程序设计的首选语言,用它训练和提高编程技术,以及开发应用程序等。
我们通过《C语言程序设计》这门课程的学习,已经能编写解决小问题的程序,对程序的开发也有了初步的认识,还掌握了C 语言的基本语法,这一过程确确实实令我们感到欣喜,有点计算机可以完成自我任务的成就感。但是,对于程序设计而言,学习C 的步伐不应该停留于此。我们最终的目的应该是掌握开发大型综合程序的方法,即遵循软件工程的开发步骤和结构化程序设计思想, 用C 语言开发出解决复杂问题的大型综合程序。可是对于多数学生来说,学习了C语言后,除了应付各种考试之外,别无它用,对Turbo C语言丰富的函数知之甚少,加上DOS环境所限,因而对C语言兴趣不大,也感到C语言比较难以掌握。
本实训就是为了让学生在学完C语言后进一步了解C语言的知识,掌握C语言在软件开发方面的使用方法,希望通过此次实训,不仅能提高学生学习C语言的兴趣,更为今后学习其它专业知识及开发程序打下坚实的基础。
本指导书中有些内容借鉴了互联网上相关程序的设计思想,在此对相关者表示衷心的感谢。
由于时间、经验及水平的原因,不当、不足之处,请大家提出宝贵意见。
编者
桂林电子科技大学信息科技学院
学生成绩管理系统
本题目设计目的是训练学生的基本编程能力,了解管理学生成绩信息系统的设计开发流程,熟悉C语言的文件各种基本实现和操作。本程序中涉及结构体、文件读写、宏等方面的知识。通过本程序的训练和制作,使学生能对C语言的文件操作等方面有一个更深刻的了解,掌握利用结构体存储实现对学生成绩管理的原理,为进一步开发出高质量的管理信息系统以及之后的其他编程方面知识的学习和理解打下坚实的基础。
1、问题定义
创建一个学生成绩管理系统。假设系统中每个学生记录只包括学号、姓名、平时成绩、期末成绩、总评成绩、总分、平均分、名次等信息。程序的运行效果如上图图所示,选择任意菜单后,实现相应功能。具体结构体设定请见以后。
程序初始主界面截图如下:
在问题定义阶段要考虑题目的可行性和需求分析,接下来进入开发阶段,完成系统设计和系统实现的任务。
2、系统设计 2.1 总体设计
本管理系统的程序主要由C语言编写,考虑到各方面的维护和需求实现考虑,程序代码总体上采用模块化编程方式设计以及编写。即将一个大的功能需求分作几个小模块来配合实现,为了降低添加和维护功能和需求的成本和时间。尽量不依赖于C语言全局变量而是通过函数调用之间的参数来传递数据。
以下是本管理系统的功能模块:
1
新建功能
主功能菜单
2.2 函数预览
1)主函数
调用其他不同功能 2)主菜单函数
输出显示界面
3)新建信息函数1(手写输入)
手动输入学生的成绩信息,包括学号、姓名、平时成绩、总评成绩 4)新建信息函数2(文件输入)
通过文件导入学生成绩信息 5)计算成绩函数
查询功能
计算功能
输出功能
计算学生试卷分数的总评成绩 6)查询成绩函数1(按学号)
按学号查询学生试卷的总评成绩
2
7)查询成绩函数2(按姓名)
按学号查询学生试卷的总评成绩
8)计算成绩函数1(计算总成绩的及格率和优秀率)
计算全班学生总评成绩的及格率和优秀率,并按优良中差输出学生人数 9)计算成绩函数2(计算总成绩的平均分和标准差)
计算学生总评成绩的平均分和标准差 10)输出成绩函数
输出全班学生的所有成绩,包括学号、姓名、总评成绩 11)导出成绩函数
将学生所有成绩的列表导出到文本score.txt中
3、系统实现
3.1功能模快(附代码)
1)主函数 int main(){ STU stu[SIZE]; int n,a,b; { char ch; ch = Menu(); int oh; switch (ch) printf(\"\\********************************************\\n\"); { printf(\"\\\* case 1: 欢迎使用 * \\n\"); printf(\"\\\* 学生试卷分数统计系统 * \\n\"); printf(\"请输入学生人数n(n<=%d):\ printf(\"\\********************************************\\n\"); scanf(\"%d\ while (1) printf(\"请输入学生平时成绩与期末成绩所占总评成绩的的比例(用整数表 { 示,满分100分):\\n\"); scanf(\"%d%d\ 3 printf(\"以下有两种输入试卷分数的方式:\\n***1.手动输入试卷分数\2.从student.txt文件中导入试卷分数***\\n\"); scanf(\"%d\
1) 输入限定
2)主菜单函数
4
/* 函数功能:显示菜单并获得用户键盘输入的选项 */ int Menu(void){ int itemSelected; printf(\"\\n【菜单】\\n\"); printf(\"1.输入记录\\n\"); printf(\"2.计算学生总评成绩\\n\"); printf(\"3.按学号查询成绩\\n\"); printf(\"4.按姓名查询成绩\\n\"); printf(\"5.计算学生及格率和优秀率\\n\"); printf(\"6.计算学生平均分和标准差\\n\"); printf(\"7.成绩列表\\n\"); printf(\"8.导出文件\\n\"); printf(\"0.退出\\n\"); printf(\"请输入你的选择:\"); scanf(\"%d\读入用户输入 */ return itemSelected; } 3)限定功能模块
限定(或者说确定)学生的人数和总评成绩的计算方式 printf(\"请输入学生人数n(n<=%d):\ scanf(\"%d\ printf(\"请输入学生平时成绩与期末成绩所占总评成绩的的比例(用整数表 示,满分100分):\\n\"); scanf(\"%d%d\
5
4)新建成绩函数1(手动输入)
/* 函数功能:手动输入分数 */ void Read_data(STU stu[],int n,int a,int b) { int i=0; 0 }
printf(\"请输入学生的学号、姓名、平时成绩和期末成绩(逗号隔开):\\n\"); for(i=0;i /* 函数功能:从文本student.txt中导入试卷分数 */ void Read_data1(STU stu[],int n,int a,int b) { } int i; FILE *fp; if((fp=fopen(\"student.txt\{ printf(\"打开文件student.txt失败!\\n\"); exit(0); } for(i=0;!feof(fp);i++) { fscanf(fp,\"%ld\ fscanf(fp,\"%s\ fscanf(fp,\"%d\ fscanf(fp,\"%d\} fclose(fp); for(i=0;i /* 函数功能:计算学生试卷分数的总评成绩 */ void Total_mark(STU stu[],int n,int a,int b) { int i; for(i=0;i /* 函数功能:按姓名查询学生试卷的总评成绩 */ void Sortbyname(STU stu[],int n) { char named[10]; int i; 9 printf(\"请输入要查找的学生姓名:\"); scanf(\"%s\ for(i=0;i 11)输出成绩函数 /* 函数功能:输出全班学生的所有成绩 */ void Show_data(STU stu[],int n) { int i; for(i=0;i 12 typedef struct student{ long num; char name[10]; int score[3]; }STU; int Menu(void); void Read_data(STU stu[],int n,int a,int b); void Read_data1(STU stu[],int n,int a,int b); void Total_mark(STU stu[],int n,int a,int b); void Sortbynum(STU stu[],int n); void Sortbyname(STU stu[],int n); void Count_pass(STU stu[],int n); void Count_average(STU stu[],int n); void Show_data(STU stu[],int n); void Write_data(STU stu[],int n); int main(){ STU stu[SIZE]; int n,a,b; char ch; int oh; printf(\"\\********************************************\\n\"); printf(\"\\\* 欢迎使用 * \\n\"); printf(\"\\\* 学生试卷分数统计系统 * \\n\"); printf(\"\\********************************************\\n\"); while (1) { ch = Menu(); switch (ch) { case 1: printf(\"请输入学生人数n(n<=%d):\ scanf(\"%d\ printf(\"请输入学生平时成绩与期末成绩所占总评成绩的的比例(用整数表示,满分100分):\\n\"); scanf(\"%d%d\ printf(\"以下有两种输入试卷分数的方式:\\n***1.手动输入试卷分数\2.从student.txt文件中导入试卷分数***\\n\"); scanf(\"%d\ switch (oh) 13 { case 1: Read_data(stu,n,a,b); break; case 2: Read_data1(stu,n,a,b); break; default:printf(\"输入菜单序号错误!\"); } break; case 2:Total_mark(stu,n,a,b); break; case 3:Sortbynum(stu,n); break; case 4:Sortbyname(stu,n); break; case 5: Count_pass(stu,n); break; case 6: Count_average(stu,n); break; case 7:Show_data(stu,n); break; case 8:Write_data(stu,n); break; case 0: printf(\"\\********************************************\\n\"); printf(\"\\\* 感谢使用 * \\n\"); printf(\"\\\* 学生试卷分数统计系统 * \\n\"); printf(\"\\********************************************\\n\"); exit(0); default:printf(\"输入菜单序号错误!\"); } } return 0; } /* 函数功能:显示菜单并获得用户键盘输入的选项 */ int Menu(void){ 14 int itemSelected; printf(\"\\n【菜单】\\n\"); printf(\"1.输入记录\\n\"); printf(\"2.计算学生总评成绩\\n\"); printf(\"3.按学号查询成绩\\n\"); printf(\"4.按姓名查询成绩\\n\"); printf(\"5.计算学生及格率和优秀率\\n\"); printf(\"6.计算学生平均分和标准差\\n\"); printf(\"7.成绩列表\\n\"); printf(\"8.导出文件\\n\"); printf(\"0.退出\\n\"); printf(\"请输入你的选择:\"); scanf(\"%d\读入用户输入 */ return itemSelected; } /* 函数功能:手动输入分数 */ void Read_data(STU stu[],int n,int a,int b) { int i=0; printf(\"请输入学生的学号、姓名、平时成绩和期末成绩(逗号隔开):\\n\"); for(i=0;i 15 fscanf(fp,\"%d\ fscanf(fp,\"%d\ } fclose(fp); for(i=0;i void Sortbynum(STU stu[],int n) { int number,i; printf(\"请输入要查找的学生学号:\"); scanf(\"%d\ for(i=0;i /* 函数功能:按姓名查询学生试卷的总评成绩 */ void Sortbyname(STU stu[],int n) 16 { char named[10]; int i; printf(\"请输入要查找的学生姓名:\"); scanf(\"%s\ for(i=0;i /* 函数功能:计算全班学生总评成绩的及格率和优秀率,并按优良中差输出学生人数 */ void Count_pass(STU stu[],int n) { int i,pass_num,t[4]; float passrate; memset(t,0,sizeof(t)); for(i=0;i 17 void Count_average(STU stu[],int n){ int i; double sum=0,aver,temp=0,standard; for(i=0;i void Show_data(STU stu[],int n) { int i; for(i=0;i void Write_data(STU stu[],int n) { FILE *fp; int i; if((fp=fopen(\"score.txt\ { printf(\"打开文件失败!\\n\"); exit(0); } fprintf(fp,\"以下各项分别对应学号、姓名、平时成绩、期末成绩和总评成绩:\\n\"); for(i=0;i fprintf(fp,\"%ld\%s\%d\%d\%d\\n\.score[0],stu[i].score[1],stu[i].score[2]); } fclose (fp); } 4、系统维护 经测试与调试确认软件无错时,开发就告一段落,这时可以交付软件供用户使用,但是在软件的使用过程中还会面临更加漫长的工作,即软件维护。一般维护的工作有:更改使用中发现的错误;为适应实际环境而对程序进行修改;为满足新的需求而对程序作必要的改进等等,一个好的程序不仅是通过好的编程技术实现,还要通过好的编程风格和设计方式来达到最低成本的代码维护和新需求的实现。 4.1 调试和测试 一般情况下,为解决一个问题所编写的程序代码较长,可能包括几百条甚至成千上万条语句。在检查并排除所有语法错误后,还会有不易发现的逻辑错误,因此要对程序进行认真仔细的测试与调试。 通常情况下语法错误造成的编译错误可以在运行时期前解决修改,比如多重指针的解除引用赋值造成的编译错误可以通过添加对应的括号来实现等。但一些错误比如说逻辑错误和运行时错误就得等到程序运行时检查或者崩溃时候才能知晓,比如空指针引用和浮点变量存储除法结果但忘记整数除法的例外情况。但捕捉这种错误也可以通过一定的方法能在使用前排除。 测试可按模块测试、组装测试和确认测试的步骤进行。 (1)模块测试就是分别对各模块进行测试的过程。在编写一个模块后应立即对其进行测试,因为这时对模块记忆深刻,而且单个模块相对较小,所以容易构造测试数据,能方便地检查和改正错误。 (2)组装测试就是把所有模块(应该是通过模块测试的模块)按预先制定的计划逐步组装和测试的过程。一般情况下,各模块之间要相互传递数据和控制信息,因此组装测试的主要任务是发现模块接口中的错误。 (3)确认测试是最后一个步骤,一般在将软件交付用户之前,应确认软件是否确实满足用户的要求,通常使用接近实际的用例进行测试。 5、归纳总结 5.1 开发经验 19 通过对本项目的开发,体会到要掌握以下几点内容。 大程序的设计风格。按“自顶向下,逐步细化,模块化”的方法进行程 序设计。在设计功能的时候还要考虑合适的算法,也要注意功能之间的依赖,必要时将重复实现的功能独立出来可以达到代码复用。 编写主函数,并进行测试与调试。当被调函数又需要调用其他函数时, 也要遵循逐步细化的原则。C语言提供丰富的库函数,编程序时要善于使用库函数,避免不必要的劳动。 定义函数时,应选好参数的个数和数据类型,也要想清楚函数的职责和 具体实现。 文件使用方法。文件使用完毕后应及时关闭,读写前判断文件是否打开 成功。 5.2 实训中遇到的问题及解决方法 在实现表达式查询中遇到要获取指定的成员值或者赋值给它,但C语言本身并没有支持运行时类型检查和其他操作。因此不能通过运行时的类型判断来实现功能,但上网查了资料可以通过if判断实现编译时代码展开值判断功能来获取结构体成员的值。 5.3 设计中尚存的不足之处 关于这次的程序,也有挺多不足的地方。首先,我觉得程序还不够完善,没能实现比较好的统计功能和基于位置的学生信息查找功能。而且借助于宏,虽然能使一些代码更加简洁,但在某种程度上也是降低了代码的可读性。 5.4 感想和心得体会 通过这次实训,我深有体会,要把所学的理论知识运用于解决实际问题不仅要付出艰辛的劳动,还要有付出脑力来设计框架和实现功能。这次实训让我进一步理解了“编程是什么”,“如何去编程”,“编程的目的又是什么”,由此实训我发现自己依旧没有能力驾驭一个框架从无到有的设计,这不仅是因为我的能力有限,更是经验困乏的具体表现,但也因为如此我也激发了我对编程的好奇心和好胜心。 在整个实训过程中,我能够坚持虚心的向老师以及同学请教问题,它使我明白了查找文档和使用搜索引擎的重要性,更让我懂得了如何跟老师同学去相处、去沟通。没有老师和同学们的无私帮助,我不可能圆满完成这次实训任务。感谢帮助过我的所有老师和同学们,要列出所有帮助过我的人的名字是不现实的,因为有些困难是通过因特网解决的,在此,谨向他们一并表示感谢! 6、参考资料 [1] 谭浩强. C程序设计(第三版). 清华大学出版社, 2005 [2] Stephen Prata. C Primer Plus(第五版). 人民邮电出版社出版, 2005 [3] Sedgewick. 算法(第四版). 人民邮电出版社,2012 [2] 李凤霞. C语言程序设计教程. 北京理工大学出版社, 2003 20 [3] 郭翠英. C语言课程设计案例精编. 北京.中国水利出版社,2004 [6] 马尚风等. C语言程序设计实训教程. 北京.科学出版社, 2003 [7] 张高煌. C语言程序设计实训. 北京.中国水利出版社,2001 21 因篇幅问题不能全部显示,请点此查看更多更全内容