C课程设计报告二.docx
《C课程设计报告二.docx》由会员分享,可在线阅读,更多相关《C课程设计报告二.docx(33页珍藏版)》请在冰豆网上搜索。
C课程设计报告二
目录
1题目与要求2
1.1问题提出2
1.2本系统涉及的知识点2
1.3功能要求2
2功能设计3
2.1算法设计3
2.2模块图4
2.3部分模块流程图4
3程序代码设计9
3.1主菜单模块9
3.2读文件模块9
3.3增加记录模块9
3.4删除记录模块10
3.5排序模块10
3.6修改记录模块10
3.7显示模块11
3.8查询模块11
4程序设计结果12
4.1菜单12
4.2增加记录12
4.3删除记录13
4.4排序记录13
4.5修改记录13
4.6显示记录14
4.7查询记录14
5程序设计总结15
参考文献16
附录:
程序清单17
1题目与要求
1.1问题提出
本人计划用C语言编写一个实用的小型通讯录系统,主要用来进行电话薄管理。
通过该系统,可以方便查询通讯录中成员的详细信息(姓名,电话,E-mail等)。
同时可以对通讯录的成员进行显示,增加,删除,查询,排序等一系列操作。
1.2本系统涉及的知识点
结构、数组、循环、函数、分支、指针、文件
1.3功能要求
设计一个实用的通讯录管理系统。
系统以菜单方式工作,要求界面友好,易于操作,能以简便高效的方式对通讯录进行管理和检索。
具体要求:
(1)录入:
通讯录信息包括:
姓名,电话,E—mail,院系。
以结构数组或数据文件的形式存放通讯录信息。
(2)更新:
能增加、删除通讯录信息。
(3)浏览:
按学号为序或姓名为序进行通讯录信息浏览。
(4)查询:
能实现指定联系人信息查询功能。
2功能设计
2.1算法设计
本系统需要实现的功能要求:
1、利用switch语句设计如图1所示的主菜单,通过上下移动光标选择相应的选项。
包括:
菜单名、作者、各个操作。
图1通讯录系统主菜单
2、该菜单中每一个选项调用一个函数,选择其中一个选项后,进入相应的操作界面实现一个相应的功能。
根据所选菜单编写相应代码:
1)主函数main:
有两重循环,第一重打印菜单,第二重处理按键;
2)读文件子函数readrecord:
读文件,若不存在则新建并写入初始化后的数组,返回记录个数;
3)增加记录子函数add:
任意位置按Esc键退出,返回记录总数,并于主菜单显示增加的个数;
4)删除记录子函数delete:
输入姓名,姓名重复则删除;
5)排序子函数order:
可按姓名或电话按升序排序,主菜单中显示排序情况;
6)修改记录子函数modify:
姓名重复,进行修改操作;
7)显示所有记录子函数print:
由pgup、pgdn、home、end及上下键控制;
8)查询记录子函数find:
直接输入姓名或电话,则显示匹配内容,姓名为纯数字者不显示;
9)保存记录子函数save:
保存,若磁盘故障或已满则退出;
10)一些键盘操作子函数:
接受键盘的上下、翻页操作。
2.2模块图
图2通讯录系统模块图
2.3部分模块流程图
1、主函数流程图:
图3主函数流程图
2、读文件子函数流程图:
图4读文件子函数流程图
3、增加记录子函数流程图:
图5增加记录子函数流程图
4、删除记录子函数流程图:
图6删除记录子函数流程图
5、修改记录子函数流程图:
图7修改记录子函数流程图
6、查询记录子函数流程图:
图8查询记录子函数流程图
7、排序子函数流程图:
图9排序子函数流程图
8、显示子函数流程图:
图10显示子函数流程图
3程序代码设计
3.1主菜单模块
1)函数原型:
main()。
2)功能:
利用strcpy图形操作函数和gotoxy取坐标函数完成主菜单的显示,同时利用do…while语句逐个输出菜单选项,接着用do…while和switch语句判断光标在菜单中的移动,或用户直接输入标号,来判断该进行的操作。
3)变量及类型:
inti,n=0,ex=0,y=8;整型形参,循环控制变量,以及存放记录数等。
charch;字符变量,存放用户输入的操作。
structpersonpsn[100];接收文件中传过来的记录信息。
4)说明:
用户可通过上下移动屏幕上的光标选择想要进行的操作,退出时可以选择保存退出和不保存退出。
3.2读文件模块
1)函数原型:
intreadrecord(structpersonpsn[],intn)。
2)功能:
利用fopen函数打开文件,并用if语句判断文件是否存在,若存在用for语句循环打开取出记录,若不存在用for语句新建有存放100个记录的空间的文件。
3)变量及类型:
inti,rcd=1;整型变量,循环控制变量i,是否有记录表示变量rcd。
FILE*fp;文件类型指针。
4)说明:
在打开文件后取出文件中包含的记录数并显示在屏幕上,同时将文件的路径也显示出来。
3.3增加记录模块
1)函数原型:
intadd(structpersonpsn[],intn)。
2)功能:
利用rtnstr函数接收用户的输入,用if语句分别判断用户的输入是否为空,若为空break结束,输入完毕后break结束,判断记录数是否已满,若满返回主菜单,否则继续接收用户输入,或用户输入返回命令。
3)变量及类型:
inti,cnt=1;整型变量,循环控制变量i,用户输入信息变量cnt。
intt=n;整型变量,当前输入记录数。
4)说明:
将用户输入的记录存入相应的空间,等待用户最后的保存到文件。
3.4删除记录模块
1)函数原型:
intdelete(structpersonpsn[],intn)。
2)功能:
利用rtnstr函数接收用户的输入,用if语句判断是否有输入,若有输入,用for循环语句将输入的名字同记录逐个进行比较,用if语句判断记录中是否有与输入的名字相同的记录,若有删除,用do…while语句和if语句判断是否删除。
3)变量及类型:
inti,indx,num=0,cnt=1;整型变量,循环控制变量i,记录编号变量indx,记录是否存在变量num,用户输入信息变量cnt。
charch;字符变量,存放用户的输入。
charstr[14];字符数组,存放记录姓名。
4)说明:
在执行删除操作的过程中,有多次判断,判断用户是否输入姓名;判断用户输入的需删除的记录序号;判断是否确认删除。
最后还要输出要删除的记录信息。
3.5排序模块
1)函数原型:
voidorder(structpersonpsn[],intn)。
2)功能:
利用do…while语句和getch函数接收用户的输入,if语句判断输入的字符,再用for语句和if语句对记录进行排序。
3)变量及类型:
charch;字符变量,存放用户的输入。
inti,j,k;整型变量,循环控制。
structpersontemp;结构体变量,存放每条记录的详细信息。
4)说明:
排序采用姓名开头字母从A&a到Z&z排,电话号码采用数字从小到大排。
都采用冒泡法排序。
3.6修改记录模块
1)函数原型:
voidmodify(structpersonpsn[],intn)。
2)功能:
利用rtnstr函数接收用户的输入,用if语句判断是否有输入,若有输入,用for循环语句将输入的名字同记录逐个进行比较,用if语句判断记录中是否有与输入的名字相同的记录,若有用rtnstr函数接收用户输入的修改信息,用if语句判断并修改。
3)变量及类型:
inti,indx,num=0,cnt=1;整型变量,循环控制变量i,记录编号变量indx,记
录是否存在变量num,用户输入信息变量cnt。
charstr[14];字符数组,存放记录姓名。
structpersontemp;结构体变量,存放每条记录的详细信息。
在输入修改信息的过程中,若只需修改其中一项,其它项可以不输入,且随时可按ESC结束修改返回,显示该记录。
3.7显示模块
1)函数原型:
voidprint(structpersonpsn[],intn)。
2)功能:
嵌套使用do…while语句、for语句和if语句,控制记录的输出显示。
3)变量及类型:
inti,k=0,l=0,j=n/10+(n%10?
1:
0);整型变量,循环控制变量i,当前显示记录条数l,页数j。
charch;字符变量,用户的输入。
4)说明:
控制每页显示十条记录,并可以用键盘上下键、pgup键、pgdn键、home键以及end键查看记录。
3.8查询模块
1)函数原型:
voidfind(structpersonpsn[],intn)。
2)功能:
利用rtnstr函数接收用户的输入,用if语句判断是否有输入,若有输入,用for循环语句将输入的名字同记录逐个进行比较,用if语句判断记录中是否有与输入的名字相同的记录,若有显示出来。
3)变量及类型:
inti,num=0,cnt=1;;整型变量,循环控制变量i,记录是否存在变量num,用户输入信息变量cnt。
charstr[15];字符数组,存放记录姓名。
4)说明:
查询时输入姓名或者电话号码中的任意一个即可。
4程序设计结果
4.1菜单
图11输出菜单结果图
4.2增加记录
图12增加记录结果图
4.3删除记录
图13删除记录结果图
4.4排序记录
图14排序方法结果图
4.5修改记录
图15修改记录结果图
4.6显示记录
图16显示所有记录图
4.7查询记录
图17查询记录结果图
5程序设计总结
在这短短的一周内,我通过一个程序设计的练习,回顾了这一年里所学的C语言的知识,也对其有了更深的了解!
同时,我还学习了一些C语言的拓展知识,如数据结构、c++。
通过这次实习我也了解都自己在知识掌握上的漏洞和一些实际操作上的不足之处。
我也知道了自己今后需要努力的方向!
我这次选的题目是实用小型通讯录系统。
通过几天的有序工作,我的程序渐渐的完成了。
结果,进入调试阶段,出现了很多问题,程序运行结果不跟想象的一样。
我又开始不断的阅读程序、调试、修改、运行,花了我很多的时间和劲力。
最后,终于运行成功了。
这时,我很高兴,得到了成功的喜悦。
我又一次在实践中成长了许多。
调试过程中遇到的主要问题
由于本程序是分模块设计的,所以运行时选择完任务并且执行完任务后,又会继续回到用户选择界面,供用户继续选择任务并执行任务,整个程序以文件形式读写,所以每次都可对输入的数据进行保存。
对于本程序的调试运行,总体上情况良好。
但是,其中也出现了一些小问题。
我发现的主要问题有:
使用getchar和gerche的差别:
在main函数中,对于变量ch的赋值,如果使用getchar(),则会使运行界面多显示一次用户选择界面,并且也显示Inputerror的标志,但是,如果使用getche()就不会出现这种情况了。
对于出现这种情况的原因,我找了一些资料,原因大致如下。
ch=getche()是从键盘上带回显的读入一个字符送给字符变量ch,而getchar()函数也是从键盘上读入一个字符,并带回显,但是它要等待输入直到按回国才结束,回车前的所有输入字符都会逐个显示在屏幕上,但只有第一个字符作为函数的返回值。
通过这次实践,我相信,只要自己在每一次实践中都能仔细思考,课程设计其实都不会很难,关键在于自己能不能认真思考,能不能亲自动手做实验,而不是想着其他人的劳动果实,其次你还要多操作,只有多操作才能从中发现问题,才能及时向老师和同学请教,解决问题,从而更好的掌握书本中知识。
实践课不在于你做得好不好,关键在于你能否认真去对待,在于你能否通过这次设计对课本上知识有了更深刻的认识,在于能否从中学到书本上学不到的知识。
因此,我会认真地对待我的每一次实验。
参考文献
[1]谭浩强,C程序设计(第三版),清华大学出版社,2005-11.
[2]刘振安,孙忱,刘燕君,C程序设计课程设计,机械工业出版社,2004-09.
[3]许秀林,程序设计基础教程,中国电力出版社,2009-08
[4]汪诗林,数据结构算法与应用,机械工业出版社,2000-1-1.
[5]刘大有,数据结构(C语言版),高等教育出版社,2004.
附录:
程序清单
实用的小型通讯录源代码如下:
#include
#include
#defineBack8
#defineEnter13
#defineEsc27
#definehome71
#defineend79
#defineupkey72
#definednkey80
#definepgup73
#definepgdn81
structperson{
charname[14];
chartel[13];
chareml[22];
chardpmnt[22];
};
intsavstate=1;
intbarup(inty)/*光条上移*/
{
if(y>=8)
{
inti;
struct{unsignedcharch;unsignedcharattr;}t;
for(i=4;i<=30;i++)
{
gettext(i,y,i,y,&t);
t.attr=0x07;
puttext(i,y,i,y,&t);
}
y=y-2;
for(i=4;i<=30;i++)
{
gettext(i,y,i,y,&t);
t.attr=0x70;
puttext(i,y,i,y,&t);
}
}
returny;
}
intbardn(inty)/*光条下移*/
{
if(y<=18)
{
inti;
struct{unsignedcharch;unsignedcharattr;}t;
for(i=4;i<=30;i++)
{
gettext(i,y,i,y,&t);
t.attr=0x07;
puttext(i,y,i,y,&t);
}
y=y+2;
for(i=4;i<=30;i++)
{
gettext(i,y,i,y,&t);
t.attr=0x70;
puttext(i,y,i,y,&t);
}
}
returny;
}
intrtnstr(charary[],intl,intm)/*对按键逐个测试,排除部分非法输入,按后退键修改,Enter键确认*/
{
inti,x,y;charch;
for(i=0;i<=m;i++)
{
x=wherex();y=wherey();
if(i{
ary[i]=getch();
if(ary[i]==0)
{
getch();i=i-1;continue;
}
}
clreol();
if(i==m)
do{
ch=getch();
if(ch==0)getch();
if(ch==Esc)return0;
if(ch==Enter){ary[m]='\0';return1;}
if(ch==Back)break;
gotoxy(x+m-i,y);clreol();
cprintf("#Can'tbemorethan%dletters.",m);
gotoxy(x,y);
}while
(1);
if(ary[i]==Esc)return0;
if(ary[i]==Back&&i==0){i=i-1;continue;}
if(ary[i]==Enter)
{
if(i>=l){ary[i]='\0';return1;}
else{
gotoxy(x+m-i,y);clreol();
cprintf("#Can'tbelessthan%dletters.",l);
gotoxy(x,y);i=i-1;continue;
}
}
if(ary[i]==Back&&i>0||ch==Back){gotoxy(x-1,y);clreol();i=i-2;ch=0;continue;}
if(m==3||(l==7&&m==12)){if(ary[i]<48||ary[i]>57){i=i-1;continue;}}
putchar(ary[i]);
}
}
intreadrecord(structpersonpsn[],intn)/*读文件。
若不存在则新建并写入初始化后的数组,返回记录个数*/
{
inti,rcd=1;FILE*fp;
if((fp=fopen("C:
\\zhyx.c","rb"))==NULL)
{
rcd=0;
if((fp=fopen("C:
\\zhyx.c","wb"))==NULL)
{
printf("Cannotopenfile!
");
returnn;
}
}
if(rcd==0)
for(i=0;i<100;i++)
fwrite(&psn[i],sizeof(structperson),1,fp);
else
for(i=0;i<100;i++)
{
fread(&psn[i],sizeof(structperson),1,fp);
if(psn[i].name[0]=='\0')break;
n++;
}
fclose(fp);
printf("Thereare%drecordsnow.\nRecordsinC:
//zhyx.c",n);
returnn;
}
intadd(structpersonpsn[],intn)/*增加记录。
任意位置按Esc键退出,返回记录总数,并于主菜单显示增加的个数*/
{
inti,cnt=1;intt=n;
while(n<100)
{
clrscr();
printf("\n\nAdded%d.\nPleaseinputtheinformation,Escbacktomenu:
\n\n\n\n",n-t);
printf("name:
");
cnt=rtnstr(psn[n].name,2,13);
if(cnt==0)break;
printf("\n\nphonenumber:
");
cnt=rtnstr(psn[n].tel,7,12);
if(cnt==0)break;
printf("\n\nemail:
");
cnt=rtnstr(psn[n].eml,7,21);
if(cnt==0)break;
printf("\n\ndepartment:
");
cnt=rtnstr(psn[n].dpmnt,2,21);
if(cnt==0)break;
printf("\n\nRecordaddedsuccessfully!
");
n++;
}
if(n==100)
{
printf("\n\nTherecordnumberhasreached100,can'taddanymore!
");
getch();
}
clrscr();
if(cnt==0)psn[n]=psn[n+1];
if(t!
=n)
{
savstate=0;
if(n-t!
=1)printf("Added%drecords.\n",n-t);
elseprintf("Added1record.\n");
}
returnn;
}
intdelete(structpersonpsn[],intn)/*删除一记录*/
{
inti,indx,num=0,cnt=1;charch;charstr[14];
printf("\n\n\n\nDeletename:
");
cnt=rtnstr(str,2,13);str[13]='\0';
if(cnt==0){clrscr();returnn;}
printf("\n");
for(i=0;iif(strcmp(psn[i].name,str)==0)
{
num++;
printf("\n%-2d%-14s%-15s%-23s%-22s",i,psn[i].name,psn[i].tel,psn[i].eml,psn[i].dpmnt);
if(num==1)indx=i;
}
if(num==1)
{
printf("\n\nFind1recod.Deleteit(Y/N)?
:
");
do{
ch=getch();
if(ch=='Y'||ch=='y')
{
clrscr();
printf("Deletedarecord!
name:
%s",str);
for(i=indx;ipsn[i]=psn[i+1];
savstate=0;
n--;
returnn;
}
else
if(ch=='N'||ch=='n'){clrscr();returnn;}
}while
(1);
}
if(num>1)
{
printf("\n\nFind%drecods.Inputthenumberbeforearecordtodeleteit:
\n\n",num);
cnt=rtnstr(str,1,3);
if(cnt==0){clrscr();returnn;}
cnt=strlen(str);
if(cnt==3){clrscr();printf("Indexerror!
");returnn;}/*借用cnt(continue)*/
if(cnt==1)cnt=str[0]-48;/*续借,indx还要用到*/
else
if(cnt==2)cnt=(str[0]-48)*10+str[1]-48;
if(cnt{
clrscr