您好,欢迎访问三七文档
当前位置:首页 > 临时分类 > C语言课程设计――通讯录
C语言课程设计——通讯录目录:一:系统功能1.系统总功能对通讯录进行必要的管理,快速查询需要的内容。2.系统结构总框架二:功能模块描述1.数据结构由于使用静态数组需要预先估计记录数,所以先预定义一个常熟M,表示记录数,也就是数组的大小,记录联系人的信息至少应有姓名、单位、电话,所以定义每个数组元素的类型为结构体。由于数组存储是采用顺序存放,在内存空间中占用连续空间,所以若干条记录通讯录的管理实质就是对顺序存储的线性表的管理。结点结构如下:#defineM50Typedefstruct{Charname[20];Charunits[30];Chartele[10];}ADDRESS;2.main()主函数程序采用模块化设计,主函数是程序的入口,各模块独立,可分块调试,均由主函数控制调用。控制功能的实现通过循环执行一个开关语句,该语句的条件值是通过调用主菜单函数得到的返回值,根据该值,调用相应的各功能函数,同时设置一个断点,即当返回值为一定条件时运行exit()函数结束程序,以免造成死循环。N—S图主程序查找插入删除保存读入按序号查找拷贝排序退出显示输入快速查找3.menu_select()主菜单直接利用输出函数printf输出字符串,在屏幕上显示一个菜单,并显示一个提示输入选项,输入0~11之间的数字,将此数字作为菜单函数的返回值返回主函数,主函数根据这个数字调用相应的功能函数。制作简便,操作简单。由于程序中很多地方用了字符串输入语句,会造成下一个字符不能正确读入,为了在程序调用执行了各个函数能够清晰地看到菜单,并输入新的选项,首先写了一条输出信息,printf(“pressanykeyentermenu……\n”)表示按任何键继续,一条读字符语句getch()等待输入字符,按任何键即可进入主菜单。读者可以将这两条语句加上注释不执行来体会它的功能。按照所见即所得的方式直接设计输出菜单,输出字符串,达到菜单效果,将精力主要放在程序功能的实现上,利用do循环语句,一直执行scanf(“%s,s)语句,让用户输入0~11之间的数,按照字符串的形式输入,然后执c=atoi(s),将字符串转化为数字,返回主函数,如果输入范围不是0~11,则循环等待重新输入。既然是数字选项,为什么不用整数格式输入,而要按字符串输入,再将其转换呢?如果按照整数格式输入,当用户输入了非数字字符,例如a和b等,由于类型不同将导致程序出错,所以对于不参加与运算的数据,表面上看是数字,也应将其设为字符处理,例如电话号码,千万不要设为整数类型。程序设计技术巧很多,所以读者在编程调试中应注意并仔细体会。4.enter()输入记录输入记录时按照一条一行的格式输入,每个数据之间用空格分隔,较为清晰,且能直接反映数据之间的关系。但由于scanf函数的特性,在输入时,数据用回车分隔也是可以的,但与界面设计不吻合。for输入任意字符输出菜单直到0C11输入s的值switch:0~11选择需要的功能0:输入和保存1:显示2:查找3:删除4:插入5保存6:读入7:按序号查找8:拷贝9:排序10:快速查找11:退出由于记录并不是一次性全部输入,而是随时填加和删除的,而预先开辟的空间数往往大于实际的记录数,所以程序设计为首先输入准备输入的记录数n,然后用for循环语句循环n次,输入记录。通讯录的每一条记录有三个字段,都是字符串类型,用格式输入scanf(“%s%s%s”,t[i].name,t[i].units,t[i].tele)完成输入,三个字段用空格分隔。输入完一条按回车键,继续输入下一条,达到规定的记录数,输入停止,返回记录数到主函数。N-S图5.显示所有记录通讯录建立好后,更频繁的操作是显示和查找记录,本函数实现显示所以记录功能。将主函数传递过去的数组输出,用for循环,循环次数由参数长度决定。输出时,为了格式美观清晰,设计一定的格式输出,注意利用格式输出函数,根据字段的长度设定输出的长度,每输出10个记录暂停一下,按任意键继续。N—S图6.sarch()和find()查找记录查找指定姓名的记录,采用顺序查找法。首先要输入要查找记录的名字,然后顺序查找结果,如果没找到,则输出没找到的信息,否则,显示找到的记录信息。因为程序多次用到了查找和显示记录,例如删除记录中,所以编写了一个find()函数,专业进行查找。从第一条记录开始,将记录中的姓名字段和待比较的姓名字符串s进行比较,一旦相等,程序结束,返回该记录的下标号i,也就是记录所在的序号;如输出显示记录的格式for(i=0;in;i++)输出记录判断输出是否达到10条是否提示按任何键继续end输入要输入的记录数输出按此格式输入for(i=0;in;i++)输入记录果不相等,则继续下一条比较,所以记录比较完毕,循环结束,返回此时的下标变量i值。Search()函数通过调用find()得到了整数i,判断i的值如果大于n-1,已超过实际记录数,说明所有记录都进行过比较,没有找到,查找不成功;否则,说明找到,调用输出函数print(),显示该第i条记录。N-S图7.delete()删除记录输入要删除记录的姓名,调用find函数,如果没有该记录,显示没有找到该信息;否则,调用print函数,显示记录信息,接着显示是否确实要删除,请输入确认信息整数0或1,1表示是,0表示否。如果输入了1,则系统删除信息。要删除数组中的某一条元素,实际所做的操作是将其后继记录依次前移一条,所以删除第i条记录,用for语句,从i+1开始,依次将每个字段拷贝到前一条记录的相应字段,即覆盖前一条记录,达到前移的目的,直到最后一条记录。注意前移记录的时候是逐个字段赋值,不能一个记录整体赋值。由于删除了一条记录,记录数减1,返回记录数,程序结束。N—S图8.add()插入记录输入要删除人的姓名调用fine()函数判断是超过记录数是否调出要删除记录的信息没有找到是否要删除是否删除(后一条退出到主菜纪录覆盖前一单条返回n输入要查找人的名字调用fine()函数判断是超过记录数是否没有找到调用函数print()显示信息输入要插入记录的信息,保存到临时变量temp中,然后再输入一个姓名,用字符串s表示,确定新记录插入在该记录之前,调用find()函数查找姓名为s的记录,得到该记录所在的序号,从最后一条记录开始,向后移动,即第n-2条移动到第n-1条,直到第i条移动到第i+1条,将新信息存入到第i条记录的位置。注意移动必须从后倒退,否则从第i条开始,将会覆盖后面的信息数据而出错。如果没有指定的记录,则find函数返回的i值为n,实际上一条记录也不会移动,新信息将插入到最后一个位置。N-S图9.save()保存记录到文件前面我们讲到的数据输入和输出是以终端为对象的,当程序关闭后,数据也就丢失了,所以为了能随时查阅数据,必须将数据输出到磁盘文件上保存起来,使用时在从磁盘中读入到内存中,这就用到了磁盘文件的读写操作。按照文件的读写要求,先定义一个指向文件的指针,按照wb写的方式打开文件名为record.txt的文件(名字读者可以在任意定义),如果文件不存在则系统自动创建该文件,保存在默认的文件夹下,通常是TurboC下,可以通过TurboC的菜单file-changedir修改文件保存路径,或者将文件名写上它的绝对路径,但要注意书写方式为“c:\\tc\\record.txt”。然后确认文件的打开方式,如果文件不能正常打开,则退出程序;否则,先写入记录数n,然后用循环语句,用文件格式输出语句fprintf(fp,”%-20s%-30s%-10s”,t[i].name,t[i].units,t[i]tele)逐条写入记录,每数输出一条记录,写入一条换行符号。N-S图输入插入的信息输入插入位置的姓名调用find,确定插入位置for(j=n-1;j=i;j--)从最后一个结点开始向后移动一条。当前记录拷贝到后一条将新插入记录的姓名拷贝到第i个位置文件是否为空是否将记录写入文件退出到主菜单for(i=0;in;i++)按照格式写入记录关闭文件10.load()从文件中读取记录算法思想:数据一旦输入保存到磁盘文件中后,更多的操作是将数据从文件读入内存,进行显示,查找等各项操作.按照文件的读写要求,先定义一个指向文件的指针,按照rb的方式打开已经保存好的文件record.txt,用语句fp=fopen(“record.txt”,”rb”),同时判断是否正常打开,如果文件打不开,则退出程序;否则,利用格式输入函数,先读出记录数,然后利用循环语句,用格式输入函数,fscanf(fp,”%s%s%s”,t[i].name,t[i].units,t[i].tele)将记录逐条读入,读出的记录保存在结构体数组中.由于结构体数组是用数组名作为参数,而数组名是数组存放的单元首地址,所以它是一种地址传递方式,数据的变动直接反应在参数所指的数组.而记录数是按值传递,其值的改变不会影响到主函数,为了保证数据的正确性,所以将记录数返回函数。主变量及用途:整型变量:n.用来从保存的文件中读出记录数.源程序代码:/*66*/intload(ADDRESSt[])N-S图:11.display()按序号查找记录算法思想:由于数组是按照顺序存储的,且对数组元素的访问可以直接按照其下标号实现随机访问,所以设计了按照记录位置访问记录.本函数实现的是从文件中查找,所以先用rb方式打开记录文件,输入序号i,从文件读入记录数,判断序号位置在记录数范围之内,由于记录是顺序存放,所以指定序号i的存储位置首地址应为(i-1)*sizeof(xy),利用函数fseek将记录指针移动到该位置,读出记录,调用print()函数显示它.主要变量及用途:整型变量n,用来读出记录数.源程序代码:/*77*/voiddisplay(ADDRESSt[])N-S图:文件是否为空是否输入要查找的序号退出到主菜单判断序号是否在记录范围内是否显示该记录显示不合理的信息关闭文件文件是否为空是否读人记录数退出到主菜单for(i=0;in;i++)按照格式读出记录关闭文件12.copy()复制文件为了保存数据,防止意外发生,为数据备份是很有必要的.本函数是将文件读写功能结合到一起的应用.将事先保存的记录文件按rb方式打开,然后利用文件格式读写函数将源文件中的信息写道目标文件中.主要变量及用途::整型变量n,用来读出记录数.源程序代码:/*88*/voidcopy()N-S图:13.sort()排序算法思想:冒泡排序是一种比较简单且常用的排序方法.具体的做法是假设待排序记录的排序码为K1,K2,Kn,先比较K1和K2,如果K1K2,则交换K1和K2所代表的记录,然后对K2和K3进行同样的处理,重复此过程,直到处理完Kn-1和Kn.这样从K1,K2到Kn-1,Kn的n-1此比较和交换的过程称为一次冒泡,这一步将最大的K值记录传到了最后,也是最终排序的位置.重复这样的步骤,不过第二次只需从K1,K2到Kn-2,Kn-1,作n-2次比较,这样最多作n-1次冒泡.为了减少不必要的循环,设置一个flag,表示本次冒泡是否出现过交换,如果没交换,则说明本次比较已经达到排序要求,可以结束程序了.本函数采用了冒泡排序方法,按照姓名排序,所以排序码为记录的姓名字段,对C语言来说,数组的下标从0开始的,所以n条记录的比较是从t[0].name,t[1].name开始到t[n-2].name.t[n-1].name的,因为姓名是字符串,比较用字符串比较函数strcmp实现,移动记录借助与第三者临时结构体变量temp,移动要保持整条记录的移动,所以三个字段都要移动,对于字符串赋值便捷的方式是用strcpy复制函数,否则就要用循环语句逐字符移动.冒泡排序的缺点是移动记录次数多,所以对于记录字段数越多,记录长度较长的不宜选择清屏记录文件是否为空是否退出到主菜单输入目标文件名是打开目标文件打开退出到主菜单读出文件记录数写入目标文件数for(i=0;in;i++)读入
本文标题:C语言课程设计――通讯录
链接地址:https://www.777doc.com/doc-3180429 .html