资源描述
北京联合大学
实训报告
课程名称: C语言程序设计课设
项目名称: 学籍管理系统
学 院: 信息学院 专 业: 通信工程
姓 名: 王晴 张孟欣 高源
李芳洁 郭亚勇
学 号:2009080304305 2009080304134 2009080304319
2009080304125 2009080304115
指导教师: 李红豫 成 绩:
2011年2月18日
目录
第一部分 实训题目与要求 3
1 问题提出 3
2 功能要求 3
3 任务分工 3
第二部分 设计实训题目功能 4
1 总体设计 4
2 算法设计 5
3 数据结构 15
4 程序代码设计 15
5 测试与调试 16
第三部分 实训总结 17
1 个人总结 17
2 结束语 18
附录A 程序清单 18
附录B 用户使用说明书 37
参考文献 38
第一部分 实训题目与要求
1 问题提出
学籍管理系统可广泛应用于全日制大、中小学及其他各类学校,对学生的成绩、升级、学籍变动进行综合管理和快速查询。可以节省在学籍管理花费的人力和物力,避免纸质文档易损坏,不易查找等缺点。同时可以随时随地的掌握学生信息,更简捷直白的对学生信息进行统计与管理。有助于提高学校的整体教育管理水平。
2 功能要求
1) 能够输入学生学籍信息
2) 能够游览学生学籍信息
3) 能够将学生的学习成绩按照学号排序
4) 能够计算学生平均分并排序
5) 能够统计学生成绩的分数段
6) 能够生成并打印需要补考的学生名单及退学名单
7) 删除退学学生的学籍并生成新名册
8) 对学生的学籍可以随时输入、输出、查找、修改
3 任务分工
郭亚勇:编写主程序、“求平均分并排序”模块的代码编写及主流程图绘制
王 晴:编写主模块图,“分数段排序”、“显示数据”、“删除退学学生学籍并生成新名 册”模块的代码编写及相关流程图绘制。
高 源:“成绩录入”模块与“按照学号排序”模块的代码编写及相关流程图绘制
李芳洁:“生成并打印补考通知单” 模块的代码编写及相关流程图的绘制、实训报告的编写
张孟欣:“生成并打印退学通知单”模块的代码编写及相关流程图的绘制、实训报告的编写
第二部分 设计实训题目功能
1 总体设计
模块设计:
定义各函数的主要功能:
[1] mycreat()录入数据
[2] myprint1()显示主菜单
[3] myprint2()统计成绩
[4] myprint3()处理学籍
[5] mydisplay()创新功能
[6] mynumsort()按学号排序
[7] mysort()计算平均分并排序
[8] myfenduan()统计分数段
[9] myretake()生成并打印补考通知单
[10] myselect()生成并打印退学通知单
[11] mynewcreat()生成并打印新名册
2 算法设计
1 分析主模块算法:输出主菜单后键盘输入1-4并回车,进入相应应用;若输入非法选项则会提示“非法选项”并提示是否继续。
2 分析录入成绩模块算法:创建一个文件yuan.dat,并把从键盘输入的数据(学号、姓名、成绩)存放在该文件中;每写入一组记录,文件记录数增1。建立录入成绩模块的流程图如下图所示。
3 分析按学号排序模块的算法:
4 分析计算平均分并排序的算法
5 分析统计分数段的算法
6 分析生成并打印补考通知单的算法
7 分析生成并打印退学通知单的算法
8 生成并打印新名册
9 分析创新功能中的"显示数据"的算法
3 数据结构
struct student
{
char name[10]; /*学生姓名*/
int grade[5]; /*学生分数*/
double ave; /*学生平均分*/
char num[10]; /*学生学号*/
};
4 程序代码设计
简介函数:Mydisplay()
int n=0,j=0,k=0,m=0,ww; 首先定义整型变量 n j k m ww。
struct student temp[N]={0}; 定义结构体 temp[N]
FILE*fp=NULL; 定义指针变量fp
fp=fopen("d:\\yuan.dat","r"); 此处为打开yuan.dat文件并读取其中数据 包括 学号、姓名、以及其五门功课的成绩。
if(fp==NULL)
{
printf("打开文件失败!\n");
return;
}
system("cls");
while(feof(fp)==0)
{
ww=fscanf(fp,"%23s%15s",temp[n].num,temp[n].name);
if(ww==-1) break;
for(j=0;j<5;j++)
{
fscanf(fp,"%d",&temp[n].grade[j]);
}
n++;
}此处的n记录了一共有多少位同学。
for(k=0;k<n;k++)进行循环操作,分别显示出每一位同学的信息
{
printf("%23s %15s ",temp[k].num,temp[k].name);
for(m=0;m<5;m++)
{
printf("%d ",temp[k].grade[m]);
}
printf("\n");
}
if(n==0)printf("\n 文件中无记录!\n");判断n是否为0,显示文件记录
else printf("\n 文件中共有%d个记录!",n);
fclose(fp); 关闭文件
注:完整程序请参见附录A。
5 测试与调试
测试数据类型
测试数据
预期结果
实测结果
合法数据
在主菜单中输入1
进入录入同学学籍菜单
进入录入同学学籍菜单
在创建同学学籍输入信息
在yuan.dat文件存入同学信息
yuan.dat文件有同学信息
非法数据
在主菜单中输入“a”
输出“a为非法选项”
输出“a为非法选项”
在每次完成一项是弹出“是否继续(Y/N)?”输入1
没有反应
没有反应
测试数据类型
测试数据
预期结果
实测结果
合法数据
在主菜单下输入1
进入mycreate()
进入创建学籍界面
在mycreate输入信息
放入文件中
文件中有此记录
非法数据
在主菜单输入a
输出“a为非法选项”
非法字符
在编辑菜单输入b
输出“b为非法选项”
非法字符
第三部分 实训总结
1 个人总结
王晴个人总结
一周的实训结束了,对于这次C语言实训,我对此非常重视,因为通过实训不仅仅是对所学知识的验证,也是对团队合作,处理好同学关系的锻炼,为毕业后更好的融入社会做准备。
通过实训前的商量,我们小组决定选择:学籍管理系统。老师说这个系统比较难,不过,我们并没有抱怨什么,既然选择了就应该迎头而上,只有去面对才能有解决的办法。
在工作开始初期,我们首先在一起商量,分配了工作,每个人都明确了自己的工作目标,我觉得这一点是非常重要的,因为一个大的程序,光靠一个人的精力很难完成,而一个团队恰恰解决了这个问题。不过团队之间的分工必须要明确,用什么样的函数名,定义什么样的函数,这些都是需要统一的,要不然到了最后整合的时候还是一团散沙。
编辑程序时,本以为自己掌握的知识已经足以应对了,然而真正运用到程序之中时,就感到理论与实践的偏差。刚打好的程序,编译之后总会出现很多错误,有些是由于自己马虎格式或者输入法的错误,有些则是用错了函数,这都导致运行结果不符合要求,常常一整篇程序,就因为一个小小的错误而得不到实现,在不断的找寻错误解决错误的过程中,锻炼了我的耐心和毅力,更让我不懈坚持着。
在这里我要感谢我的指导老师,那天早晨还差5分钟上课,我就由于编程问题去询问了您,您耐心的对我讲解,查询我编程的错误,将近半个小时的时间,你没有说让我自己回去自己看看这种话,我觉得您真的是一位好老师!
尽管这一周的实训结束了,但C语言的学习才刚刚开始,通过这次实训,让我更加深刻的了解C语言,熟悉了自己所学的只是,让自己更加熟练的运用C语言来编程。
李芳洁个人总结
结束一个学期的c语言学习之后,我们开始了为期一周的c语言实训课。尝试着以小组为单位,编辑一个比较复杂的程序。开始之初,我们按照所编程序进行了详细的分工,这样一来就将程序化整为零,在一定程度上降低了了难度。
在这一周的学习过程中,我对c语言编程有了更深一步的认识。C语言这门课程仅仅靠听课是远远不够的,上机训练不容忽视。通过实际编程,我看到了自己在c语言知识上的不足与漏洞。不仅学到了以前不懂的知识,而且对学过知识点有了深一步的理解。对于c语言的学习方法也有了一定的改进。学习C语言知识要有系统的,不能零零散散。应增加动手实践,不能只学理论知识。只有动手能力得到了提高,编写C语言程序和分析C语言问题的能力才能有所提高。
在这次实训中,我还感受到了团队的力量——每个人为了同一个目标而奋斗,力量凝聚在一起的感觉。当程序出现错误时,大家在一起讨论,一起想办法。通过一次次的调试,一次次的改错,直到程序运行成功,出现令大家满意的结果……感觉大家的力量都凝聚到了一起。可以说这次的成功与大家每个人的努力都密不可分。当然与我们的指导老师——李红豫老师也密不可分,她的悉心指导是我们的程序成功的桥梁。
在我看来,作为一名信息学院的学生,学习c语言是一项必不可少的任务。这次实训将我们学习c语言的能力提高了一个层次,在今后的学习生涯中我们会继续学习并熟悉这门课程。
张孟欣的个人总结
这一周的实训过的很快,通过这一次实训,我了解到了C语言编程的实用性。本次实训我的分工是编写“生成并打印退学通知单”模块。在编写过程中,我发现制定流程图的思路顺序与运行时的顺序不一定是一样的。在这部分的编写过程中我的问题主要在调用文件及循环嵌套部分,在看书与同组同学的帮助下得到了解决。
“生成并打印退学通知单”部分需要满足的功能是,筛选每个同学的不及格科目,如果不及格的科目大于3科就要求退学,并且打印出各个不及格科目的名称、成绩以及该同学的姓名、学号。由于不细心,在一开始编写的时候没有将判断某同学每科成绩的if语句与判断某同学共有几门课程不及格的if语句嵌套在一起,导致在运行时将未满足退学条件的同学的相关信息也一同显示了出来。经过调试后,发现了这个漏洞,改正后可以正常实现应有功能。其中在编写统计同学不及格科目数量的时候没有将其以数组的形式储存,而是直接用“s=s+1;”这个语句,导致最后的运行结果所有含有不及格科目的同学都被要求退学,通过改正,将该语句改成“s[i]=s[i]+1;”后,可正常运行。
通过这次编程,清楚认识到了自己的不足,犯了一些很幼稚的错误。只是课上的学习还是不够的,真正地掌握知识还需要实践。不断地摸索创新,才成将知识存入囊中。这次实训不但让我认识到了自己对于C语言学习的漏洞,我还学会了团队精神,合作才是最重要的。每个人负责不同的部分,虽然看上去是各自负责各自的部分,但是当汇总到一起的时候,也许自己的一个错误会影响到整个程序的运行。在完成这个程序的过程中,还有老师的辅导,帮我解决了不少的问题。学知识需要做活学活用,在今后的学习生活中我会更加重视细节,并且多加练习。
高源的个人总结
通过一个星期的实训课程,我深有感触。对于一个课题我在一开始构想时只有大体的思路,忽略了许多细节,只有在进行编写程序时才能意识到思路上的不足与考虑不周之处。因此在我真正做设计时发现有很多错误,有的时候要解决一个错误会花上很多时间,在做的过程中,有很多错误意想不到,有的错误却犯得很幼稚,不过正是这些错误让我在发现他们的过程中牢牢的记住了他们,并且对与我自己检查排错的能力得到很大的提高。例如在做比较函数时,我所编写的程序中对于字符串的比较出了问题。找了半天才发现char型定义的数字比较遵循字符串比较规律与普通int型数字比大小不一样。结果导致程序运行有错。这也提醒了我,对于字符串比较规律我本身就有误区,通过这次的实践与排查我弥补了自己的知识盲点。这些细小错误让我深受感慨,它告诉了我编程细心重要,养成一个好的编程习惯更重要。这次项目的完整开发,让我有项目初步的思想,这次项目的开发让我把软件生成的流程从信息的收集,再写需求,再完成后台设计到编写代码,到测试,让我知道还有很多地方的不足。更重要的是团队之间的合作,相互之间的交流,有时一个问题总是想不通,但每个队友负责的部分不同,所以想法也不同,交流之后,便有了新的思路。这次课程设计的时间很紧迫,再加上各方面的经验不足,也遇到很多问题,这个学籍管理系统还有很多地方没有完善,希望老师能谅解。总的来说,这次课程设计对我很有帮助,我发觉老师上课讲的很多东西对我们都很有用,让我受到不少的启发。
郭亚勇的个人总结
一个星期的实训结束了,从中也学到了不少知识,虽然开始对c语言的部分知识有些生疏,但经过这次实训让我对生疏的部分印象更深,同时对c语言的学习有了更深一步的认识,尤其是在文件的处理上总是出问题,我曾经还花了一下无时间写文件,读文件,可是却死活无法读取文件,顺利的写入文件,总是乱码。并且,我发现虽然对某一功能有很好的构思,但是一旦落实到实际编写程序,却并不是那么容易实现的,只有真正去编程,才能发现我学习中的错误认识,以及学习不扎实的地方和学习的不足之处。虽然在编程之间与其它同学在思路上有过分歧,但是通过讨论也让我对编程的思路上有了进步,知道该如何使程序编的更严谨,同时又要考虑较为简便的算法,更好的完成任务,同时与其他同学的合作完成一个大程序,也使我更深的体会了,合作的重要性,与其他人跟好的合作,因为有时候并不是自己一个人可以完成的任务,所以与同伴之间的协调,合作才尤为重要,有时候一个人写的程序单独运行没问题,然而与其他人和在一起时却有可能产生错误。对于文件的操作是我这次遇到的最大的难题,无法正确的读取,就意味着无法操作文件中的数据进行运算等一系列操作。无法正确的写入文件就意味着我对文件中的数据的一系列操作是无意义的,没法保存进文件,所以这两步很重要。读取文件时总是读不进去或者多读取一行导致在写入时会出现一行未知的数据,所以控制读取文件函数的返回值,令它不去读取多余的位就尤为重要。不过最后在老师的指导下终于解决了。从这次实训我学到了很多,这对我以后编程会有很大的帮助,对我终身的学习也是一种帮助。
2 结束语
经过全体同学一周的共同努力,最终完成了学籍管理系统的编写。虽然此项目还不太成熟,功能不太完整,但这是我们全体成员心血的结晶。在此对我们的所有成员表示祝贺和感谢。通过这次合作,我们认识到了团队精神以及集体荣誉感。
此外我们还要感谢我们的指导老师—李红豫老师对我们的帮助。在编写代码的过程中,我们遇到了很多棘手的难题,老师给予了我们充分的点拨与指导,对我们项目的顺利完成起到了不可或缺的作用。以此献上我们最诚挚的感谢。
附录A 程序清单
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#define N 100
void mycreat();
void mynewcreat();
void mydisplay();
void myretake();
void myselect();
void mynumsort();
void mysort();
void myprint1();
void myprint2();
void myprint3();
void myfenduan();
struct student
{
char name[10];
int grade[5];
double ave;
char num[10];
};
void myprint1()
{
char choose='\0',yes_no='\0';
do
{
system("cls");
printf (" |---------------------------|\n");
printf (" | 请输入选项编号(0-4) |\n");
printf (" |---------------------------|\n");
printf (" | 1----------录入成绩 |\n");
printf (" | 2----------统计成绩 |\n");
printf (" | 3----------处理学籍 |\n");
printf (" | 4----------显示数据 |\n");
printf (" | 0----------退出系统 |\n");
printf (" |---------------------------|\n");
printf(" ");
choose=getche();
switch(choose)
{ case '1':mycreat(); break;
case '2':myprint2(); break;
case '3':myprint3(); break;
case '4':mydisplay(); break;
case '0':break;
default :printf("\n %c为非法选项!\n",choose);
}
if(choose=='0')
{
printf("\n");
printf("感谢您的使用!\n");
break;
}
printf("\n 要继续选择吗(Y/N)?\n");
do
{ yes_no=getch( );
} while(yes_no!='Y' && yes_no!='y'&& yes_no!='N' && yes_no!='n');
} while(yes_no=='Y' || yes_no=='y');
}
void myprint2()
{
char choose='\0',yes_no='\0';
do
{
system("cls");
printf (" |-----------------------------------|\n");
printf (" | 请输入选项编号(0-4) |\n");
printf (" |-----------------------------------|\n");
printf (" | 1----------按学号排序 |\n");
printf (" | 2----------计算平均分并排序 |\n");
printf (" | 3----------统计分数段 |\n");
printf (" | 4----------返回 |\n");
printf (" | 0----------退出系统 |\n");
printf (" |-----------------------------------|\n");
printf(" ");
choose=getche();
switch(choose)
{ case '1':mynumsort(); break;
case '2':mysort(); break;
case '3':myfenduan(); break;
case '4':myprint1(); break;
case '0':break;
default :printf("\n %c为非法选项!\n",choose);
}
if(choose=='0')
{
printf("\n");
printf("感谢您的使用!\n");
break;
}
printf("\n 要继续选择吗(Y/N)?\n");
do
{ yes_no=getch( );
} while(yes_no!='Y' && yes_no!='y'&& yes_no!='N' && yes_no!='n');
} while(yes_no=='Y' || yes_no=='y');
}
void myprint3()
{
char choose='\0',yes_no='\0';
do
{
system("cls");
printf (" |---------------------------------------|\n");
printf (" | 请输入选项编号(0-4) |\n");
printf (" |---------------------------------------|\n");
printf (" | 1----------生成并打印补考通知单 |\n");
printf (" | 2----------生成并打印退学通知单 |\n");
printf (" | 3----------生成并打印新名册 |\n");
printf (" | 4----------返回 |\n");
printf (" | 0----------退出系统 |\n");
printf (" |---------------------------------------|\n");
printf(" ");
choose=getche();
switch(choose)
{ case '1':myretake(); break;
case '2':myselect(); break;
case '3':mynewcreat(); break;
case '4':myprint1(); break;
case '0':break;
default :printf("\n %c为非法选项!\n",choose);
}
if(choose=='0')
{
printf("\n");
printf("感谢您的使用!\n");
break;
}
printf("\n 要继续选择吗(Y/N)?\n");
do
{ yes_no=getch( );
} while(yes_no!='Y' && yes_no!='y'&& yes_no!='N' && yes_no!='n');
} while(yes_no=='Y' || yes_no=='y');
}
void mycreat()
{
int i=1,j=0;
struct student temp={0};
FILE*fp=NULL;
fp=fopen("d:\\yuan.dat","w");
if(fp==NULL)
{
printf("打开文件失败!\n");
return;
}
system("cls");
printf("注意:输入学号时请将所有位数保持一致不足位用0补齐。例如最大学号为1000则均保持4位有效数字。");
printf("\n 请输入第1个记录:\n");
printf(" 学号(用#结束输入):");
do
{
gets(temp.num);
}while(strcmp(temp.num,"")==0);
printf(" 姓名(用#结束输入):");
gets(temp.name);
printf(" 请输入 高数 英语 物理 编程 马哲 5组成绩(用#结束输入): ");
for(j=0;j<=4;j++)
{
scanf("%d",&temp.grade[j]);
}
while(temp.num[0]!='#'&&temp.name[0]!='#'&&temp.grade[0]!='#')
{
fprintf(fp,"%23s%15s",temp.num,temp.name);
for(j=0;j<=4;j++)
{
fprintf(fp,"%5d",temp.grade[j]);
}
fprintf(fp,"\n");
i++;
printf("\n 请输入第%d个记录:\n",i);
printf(" 学号(用#结束输入):");
do
{
gets(temp.num);
}while(strcmp(temp.num,"")==0);
printf(" 姓名(用#结束输入):");
gets(temp.name);
printf(" 请输入 高数 英语 物理 编程 马哲 5组成绩 (用#结束输入): ");
for(j=0;j<=4;j++)
{
scanf("%8d",&temp.grade[j]);
}
}
fclose(fp);
}
void mynumsort()
{
int i=0,j=0,k=0,n=0,grade=0,num=0,m=0,ww;
struct student temp[N]={0};
struct student a;
FILE *fp=NULL;
FILE *fq=NULL;
fp=fopen("d:\\yuan.dat","r");
if(fp==NULL)
{
printf("\n 打开文件失败!\n");
return;
}
system("cls");
while(feof(fp)==0)
{
ww=fscanf(fp,"%23s%15s",temp[n].num,temp[n].name);
if(ww==-1) break;
for(j=0;j<5;j++)
{
fscanf(fp,"%d",&temp[n].grade[j]);
}
n++;
}
printf("n=%d",n);
fclose(fp);
printf("\n");
for(i=0; i<n; i++)
{ k=i;
for(j=k+1; j<n; j++)
if(strcmp(temp[k].num,temp[j].num)>0)
k=j;
a=temp[i];
temp[i]=temp[k];
temp[k]=a;
}
for(k=0;k<n;k++)
{
printf("%10s号 %10s同学",temp[k].num,temp[k].name);
for(m=0;m<5;m++)
{
printf("%5d分",temp[k].grade[m]);
}
printf("\n");
}
if(n==0)printf("\n 文件中无记录!\n");
else printf("\n 文件中有%d个记录",n);
fq=fopen("d:\\std.dat","w");
if(fq==NULL)
{
printf("打开文件失败!\n");
exit(0);
}
for(i=0;i<n;i++)
{
fprintf(fq,"%23s%15s",temp[i].num,temp[i].name);
for(j=0;j<5;j++)
{
fprintf(fq,"%2d",temp[i].grade[j]);
}
fprintf(fq,"\n");
}
fclose(fq);
printf("计算已完成 保存在d:\std.dat文件当中,请查验");
}
void mysort()
{
struct student temp[N]={0},a[N]={0};
int i=0,j=0,n=0,ww=0;
FILE*fp=NULL;
FILE*fq=NULL;
fp=fopen("d:\\yuan.dat","r");
if(fp==NULL)
{
printf("打开文件失败!\n");
exit(0);
}
system("cls");
while(feof(fp)==0)
{
ww=fscanf(fp,"%23s%15s",temp[n].num,temp[n].name);
if(ww==-1) break;
for(j=0;j<5;j++)
{
fscanf(fp,"%d",&temp[n].grade[j]);
}
n++;
}
for(i=0;i<n;i++)
{
for(j=0;j<5;j++)
{
temp[i].ave=temp[i].ave+temp[i].grade[j];
}
temp[i].ave=temp[i].ave/5;
}
for(i=0;i<n;i++)
{
if(temp[i].ave<temp[i+1].ave)
{
a[i]=temp[i];
temp[i]=temp[i+1];
temp[i+1]=a[i];
}
}
fq=fopen("d:\\sort.dat","w");
if(fq==NULL)
{
printf("打开文件失败!\n");
exit(0);
}
for(i=0;i<n;i++)
{
fprintf(fq,"%23s%15s%10.2f",temp[i].num,temp[i].name,temp[i].ave );
for(j=0;j<5;j++)
{
fprintf(fq,"%2d",temp[i].grade[j]);
}
fprintf(fq,"\n");
}
fclose(fq);
printf("计算已完成 保存在d:\sort.dat文件当中,请查验");
}
void myfenduan()
{
int i=0,j=0,n=0,ww;
int b[N]={0},c[N]={0},d[N]={0},e[N]={0},f[N]={0};
struct student temp[N]={0};
FILE*fp=NULL;
fp=fopen("d:\\yuan.dat","r");
if(fp==NULL)
{
printf("打开文件失败!\n");
return;
}
system("cls");
while(feof(fp)==0)
{
ww=fscanf(fp,"%23s%15s",temp[n].num,temp[n].name);
if(ww==-1) break;
for(j=0;j<5;j++)
{
fscanf(fp,"%d",&temp[n].grade[j]);
}
n++;
}
for(i=0;i<n;i++)
{
for(j=0;j<5;j++)
{
if(temp[i].grade[j]>=90)
b[j]=b[j]+1;
else if(temp[i].grade[j]>=80)
c[j]=c[j]+1;
else if(temp[i].grade[j]>=70)
d[j]=d[j]+1;
el
展开阅读全文