C语言程序设计实习报告行编辑器学生管理系统.docx
《C语言程序设计实习报告行编辑器学生管理系统.docx》由会员分享,可在线阅读,更多相关《C语言程序设计实习报告行编辑器学生管理系统.docx(54页珍藏版)》请在冰豆网上搜索。
C语言程序设计实习报告行编辑器学生管理系统
C程序设计实习报告
题目:
简单的行编辑器(修改版)
学院:
专业:
姓名:
班级学号:
指导教师:
2009年7月3日
前言
由于我们班选题是题号和学号一一对应,所以我抽到了16题,简单的行编辑器。
刚开始时不知道什么叫行编辑器,以为这个题目有多么的神秘,第二次实习时老师说选这个题目最好换个题,与老师交流,老师建议在原有的题目上加些功能。
只是还是不知道什么叫行编辑器,上网,问同学,没有一点思路。
再一次问老师,老师说不用管它什么是行编辑器,编辑的目的是为了后面对文件进行处理,于是这一次总算有了新的思路。
等到这个题快要做完时,也明白了为什么老师说它太简单了,做完后自己感觉都有串改题目之嫌疑,原题的要求实在太简单了,自己加的功能占了程序的大部分。
8天下来感觉自己对C语言以及程序编辑的认识加深了许多。
以前觉得很难的结构体,数组,文件全部用到了,虽然并不能完全掌握,那也有一些成就感。
在这里要感谢老师以及我的同学,在整个编程中给了我很大的帮助。
1题目要求
原题:
简单的行编辑器
【要求】
(1)设置一个简单的行编辑器,每行以回车结束。
(2)数据以文件形式储存。
(3)编辑器具有查找、替换、修改数据的功能。
修改后:
修改思路是将由行编辑器生成的文件换成有关结构体的内容,建立一个结构体输入关信息,生成文件,再实现查找、替换、修改数据等的功能。
这里具体是参考书上学生成绩管理系统,实现成绩的录入,显示,查找,添加,保存等功能模块。
2需求分析
根据题目要求,由于学生信息是存放在文件中,所以应提供文件的输入、输出等操作;在程序中需要浏览学生的信息,应提供显示、查找、排序等操作;另外还应提供键盘式选择菜单实现功能选择。
3概要设计
3.1设计思想
由于原题的特点,对题目进行了一定的拓展。
本着提高自己编程能力,加深对C语言重点、难点内容的理解,添加了关于结构体、数组以及文件的运用。
将程序模块化,使程序条理清楚,制作简单,容易读懂,并能体会到程序开发的思想与方法,加深对C语言编程的认识。
3.2软件运行与开发平台
C语言,Windows平台,VC6.0,
3.3数据结构
此处选用了结构体的形式来存放每一个学生的信息,对与若干个学生采用了结构体数组。
3.4系统结构图
4详细设计
4.1主函数
主函数比较简单,只提供了输入和菜单函数的调用。
各个功能的模块用菜单方式选择。
【程序】
voidmain()
{intq,w1;
printf("\t\t****************行编辑器(修改拓展版)****************\n\n");
printf("\t\t\t\t\t072092\t周磊\t20091002238\n\n");
do
{
printf("\t\t重新录入数据请按1\t\t进入菜单请按2:
[]\b\b");
scanf("%d",&q);
if(q!
=1&&q!
=2)/*对选择数字作出判断*/
{
w1=1;
getchar();
}
elsew1=0;
}
while(w1==1);
if(q==1)/*if语句选择要进行的操作*/
enter();
else
menu();
}
4.2各功能模块设计
(1)输入模块
考虑到自己在C学习时遇到的问题,以及在考计算机二级时薄弱的地方,以及联系这个题目的要求,此处选用了结构体的形式来存放每一个学生的信息,对与若干个学生采用了结构体数组。
具体到各个数据的信息,学号和姓名采用了字符型数组,分数为整型,而平均分采用了实型。
/***************************定义结构体变量*****************************/
structstudent
{
charnum[20];/*学号*/
charname[100];/*姓名*/
intscore[3];/*分数*/
floatave;/*平均分*/
}stu[N];/*stu[N]中每个元素对应一个学生*/
N采用了宏定义的方式,可以随时在源程序中修改。
【程序】
/*************输入模块****************/
voidenter()
{
inti,n;
printf("请输入学生数量(0-%d)?
:
",N-1);
scanf("%d",&n);
printf("\n请输入数据\n\n");
for(i=0;i{
printf("\n输入第%d个学生记录\n",i+1);
input(i);/*调用输入函数*/
}
if(i!
=0)
save();/*调用保存函数*/
}
(2)浏览模块
该模块的功能是显示所有学生的记录信息,流程如图。
图4.2—2
【程序】
/*********浏览函数*********/
voidbrowse()/*浏览模块,前面多次用到*/
{
inti,n;
n=load();
printf_face();
for(i=0;i{if((i!
=0)&&(i%10==0))/*目的是分屏显示*/
{
printf("任意键继续\n");
getch();
puts("\n\n");
}
printf_one(i);
}
printf("\n\t共有%d条记录.\n",n);
printf("\n任意键返回\n\n");
getch();
menu();
}
(3)添加模块
该模块的功能是用户需要增加新的学生记录,注意新添加的内容不能覆盖原来的记录。
追加模块流程图:
【程序】
/***************添加模块********************/
voidadd()
{
inti,n,m,k;
FILE*fp;
n=load();
printf("请输入添加的学生个数(0-%d)?
:
",N-1-n);
scanf("%d",&m);/*m为添加学生的个数*/
k=m+n-1;
for(i=n;i<=k;i++)
{
printf("\n输入第%d个学生记录\n",i-n+1);
input(i);/*调用输入函数*/
}
if((fp=fopen("zhoulei.txt","ab"))==NULL)
{
printf("\n文件无法打开\n");
}
for(i=n;i<=k;i++)
if(fwrite(&stu[i],sizeof(structstudent),1,fp)==0)
printf("文件写入错误\n");
fclose(fp);
save();
}
(4)查找模块
该模块在参考程序上做的一定逻辑上的修改,可以按姓名和按学号进行查找,找到以后,可进行修改和删除信息的操作。
由于改动方便,这里的按姓名和按学号查找分了两个函数,使函数比较烦缀,故函数还可以进行优化。
【程序】
a)查找模块
/********查找函数********/
voidsearch()
{
intz,w1;
do
{
printf("请输入查找方式:
1).按姓名查找2).按学号查找[]\b\b");
scanf("%d",&z);
if(z!
=1&&z!
=2)/*对选择数字作出判断*/
{
w1=1;
getchar();
}
elsew1=0;
}
while(w1==1);
if(z==1)
search_name();/*调用按姓名查找程序*/
else
search_no();/*调用按学号查找程序*/
}
b)按姓名查找模块
这个是根据姓名查找到对应的学生记录,但在此处程序有一定的缺陷,就是如果有相同的姓名,只能查到最上面的一个,而其他的则不能找到。
后来尝试修改时发现,还需要改动其他相应的函数,故没有进行下去。
【程序】
/**********按姓名查找***************/
voidsearch_name()
{
inti,n,k,w1=1,w2,w3,w4;
structstudents;
n=load();
do
{
do
{k=-1;
printf("\n\n请输入要查找的姓名!
姓名:
");
scanf("%s",s.name);/*输入要修改的数据的姓名*/
printf_face();/*调用显示数据结构项目的函数*/
for(i=0;iif(strcmp(s.name,stu[i].name)==0)/*匹配姓名*/
{k=i;/*找到要修改的记录*/
printf_one(k);break;/*调用显示一个记录的函数*/
}
if(k==-1)
{printf("\n\n记录不存在!
");
printf("\n\n是否继续?
\n\t1).是2).否返回[]\b\b");
scanf("%d",&w1);
if(w1==1)
search();
elsemenu();
}
}
while(k==-1&&w1==1);
w4=0;w3=0;
if(k!
=-1)
{printf("\n\n请选择下一步:
\n\t1).查找其他2).修改3).删除4).返回菜单[]\b\b");
scanf("%d",&w2);
switch(w2)
{case2:
w3=modify_data(k,n);break;
case3:
{printf("\n确定删除?
\n\t1).确定2).返回[]\b\b");
scanf("%d",&w4);
if(w4==1)
stu[k].ave=0;
break;
}
}
if(w3==1||w4==1)
{
save();
printf("\n\n操作成功^_^");
printf("\n\n请选择下一步:
\n\t1).查找其他2).返回[]\b\b");
scanf("%d",&w2);
}
}
}while(w2==1);
menu();
}
c)按学号查找模块
这个函数是在按姓名查找模块的基础上做了相应的改动,由于学号具有唯一性,故不存在查不到相同学号的情况。
【程序】
/*********按学号查找程序***********/
voidsearch_no()
{
inti,n,k,w1=1,w2,w3,w4;
structstudents;
n=load();
do
{
do
{k=-1;
printf("/n/n请输入要查找的学号!
学号:
");
scanf("%s",s.num);
printf_face();
for(i=0;iif(strcmp(s.num,stu[i].num)==0)
{k=i;
printf_one(k);break;
}
if(k==-1)
{printf("\n\n记录不存在!
");
printf("\n\n是否继续?
\n\t1).是2).否返回[]\b\b");
scanf("%d",&w1);
if(w1==1)
search();
elsemenu();
}
}
while(k==-1&&w1==1);
w4=0;w3=0;
if(k!
=-1)
{printf("\n\n请选择下一步:
\n\t1).查找下一个2).修改3).删除4).返回菜单[]\b\b");
scanf("%d",&w2);
switch(w2)
{case2:
w3=modify_data(k,n);break;
case3:
{printf("\n确定删除?
\n\t1).确定2).返回[]\b\b");
scanf("%d",&w4);
if(w4==1)
stu[k].ave=0;
break;
}
}
if(w3==1||w4==1)
{
save();
printf("\n\n操作成功^_^");
printf("\n\n请选择下一步:
\n\t1).查找其他2).返回[]\b\b");
scanf("%d",&w2);
}
}
}while(w2==1);
menu();
}
/*********浏览函数*********/
voidbrowse()/*浏览模块,前面多次用到*/
{
inti,n;
n=load();
printf_face();
for(i=0;i{if((i!
=0)&&(i%10==0))/*目的是分屏显示*/
{
printf("任意键继续\n");
getch();
puts("\n\n");
}
printf_one(i);
}
printf("\n\t共有%d条记录.\n",n);
printf("\n任意键返回\n\n");
getch();
menu();
}
(5)修改模块
该模块首先要显示所有学生的信息,并采用分屏显示。
显示完所有记录后,用户输入要修改的学生的学号,根据学号查找学生记录,并提示用户修改该记录的哪部分信息。
【程序】
/*************修改函数***********/
voidmodify()
{
structstudents;
inti,n,k,w0=1,w1,w2=0;
n=load();
do
{
k=-1;
printf_face();/*调用显示数据结构项目函数*/
for(i=0;i{
if((i!
=0)&&(i%10==0))/*目的是分屏显示*/
{printf("\n\n记住你要修改的学号.任意键继续...");
getch();
puts("\n\n");
}
printf_one(i);/*调用显示一个记录的函数*/
}
do
{
printf("\n\n请输入你想要修改的学号:
");
scanf("%s",s.num);/*输入要修改的数据的学号*/
for(i=0;iif(strcmp(s.num,stu[i].num)==0)
{
k=i;/*找到要修改的记录*/
s=stu[i];/*备份当次要修改的学生记录stu[i]*/
}
if(k==-1)printf("\n\n记录不存在!
");/*当k=-1表示没有找到*/
}
while(k==-1);
printf_face();
printf_one(k);
w1=modify_data(k,n);/*修改学生记录并返回保存控制值*/
if(w1==1)
{
printf("\n操作成功^_^.\n\n是否继续修改?
\n\n\t1).是2).返回并保存\t[]\b\b");
scanf("%d",&w0);
w2=1;/*用来控制保存,使w2=1是标记已有过的修改*/
}
else
{
w0=0;
if(w2==1)
stu[k]=s;
}
if(w0!
=1&&w2==1)
save();/*w2不等于1表示在此次之前没有修改过,这是就保存用户已确认的修改并返回*/
}
while(w0==1);
printf("\n\n你所修改的内容不存在");
menu();
}
(6)排序模块
该模块在原有的排序模块上做了一定的修改,可以按照分数1,、分数2、分数3以及平均数进行由大到小的排序。
这里选择了冒泡法排序。
由于改动方便,这里的4种排序方法在程序上其实是大同小异,因此程序还需进行一定的优化。
还有一个问题就是排序结束后不能直接浏览,需要手动调用浏览模块。
其原因是在排序后调用了保存函数,而保存函数保存完毕要直接返回主菜单。
如果先进行浏览的话,所显示内容不是排序后的。
【程序】
a)排序模块
/********************排序模块********************/
voidorder()
{intm;
printf("请选择排序方式:
1).按分数1排序2).按分数2排序3).按分数3排序4).按平均分排序\n\n");
scanf("%d",&m);
switch(m)
{case1:
order_score1();break;/*分数1*/
case2:
order_score2();break;/*分数2*/
case3:
order_score3();break;/*分数3*/
case4:
order_ave();break;/*平均分*/
}
}
b)按四种方式排序
/*********按平均分排序*****************/
voidorder_ave()
{inti,j,n;
structstudents;
n=load();
for(i=0;i{for(j=i+1;jif(stu[i].ave{s=stu[i];
stu[i]=stu[j];
stu[j]=s;
}
}
save();
puts("\n\n");
menu();
}
/*********按分数1排序*****************/
voidorder_score1()
{inti,j,n;
structstudents;
n=load();
for(i=0;i{for(j=i+1;jif(stu[i].score[0]{s=stu[i];
stu[i]=stu[j];
stu[j]=s;
}
}
save();
puts("\n\n");
menu();
}
/*********按分数2排序*****************/
voidorder_score2()
{inti,j,n;
structstudents;
n=load();
for(i=0;i{for(j=i+1;jif(stu[i].score[1]{s=stu[i];
stu[i]=stu[j];
stu[j]=s;
}
}
save();
puts("\n\n");
menu();
}
/*********按分数3排序*****************/
voidorder_score3()
{inti,j,n;
structstudents;
n=load();
for(i=0;i{for(j=i+1;jif(stu[i].score[2]{s=stu[i];
stu[i]=stu[j];
stu[j]=s;
}
}
save();
puts("\n\n");
menu();
}
(7)保存模块
这个模块单独放在菜单里其实有点缀余,因为每个对文件进行写入或修改的操作都单独进行了保存。
这里文件的读写全用的是二进制,所以保存的文件直接以文本打开后会出现乱码。
【程序】
/************************保存函数*******************************/
voidsave()/*存储函数*/
{
inti;
FILE*fp;
if((fp=fopen("zhoulei.txt","w"))==NULL)/*按只写方式打开文件*/
{
printf("文件无法打开\n");/*防止文件为空,并报错*/
}
for(i=0;iif(stu[i].ave!
=0)/*stu[i].ave!
=0表示此记录已删除*/
if(fwrite(&stu[i],sizeof(structstudent),1,fp)!
=1)/*这里用二进制进行文件的读写,是文件不能通过电脑直接打开*/
printf("文件写入错误\n");
fclose(fp);
printf("\n\n保存成功!
\n\n按任意键继续\n\n");
getch();
menu();
}
/*一般的保存模块,用于各种变动之后,文件的保存*/
4.3公共函数
这里都是些在每个模块都可能用到的公共函数
(1)加载函数
/********加载函数********/
intload()
{
FILE*fp;
inti;
if((fp=fopen("zhoulei.txt","rb"))==NULL)/*以只读方式打开一个二进制文件*/
{
printf("\n无法打开文件\n");
returnNULL;
}
for(i=0;!
feof(fp);i++)
fread(&stu[i],sizeof(structstudent),1,fp);
fclose(fp);
return(i-1);/*返回记录个数*/
}
(2)学号输入函数
/**********学号输入函数************/
voidno_input(inti,intn)/*i表示第i个学生的信息,n表示比较到第n个学生*/
{
intj,k,w1;
do
{w1=0;
printf("学号:
");
scanf("%s",stu[i].num);
for(j=0;stu[i].num[j]!
='\0';j++)/*学号输入函数,作了严格的规定*/
if(stu[i].num[j]<'0'||stu[i].num[j]>'9')/*判断学号是否为数字*/
{
puts(