一、实践的目的和要求加深对C语言课程所学知识的理解,进一步巩固C语言算法规则.学会编制结构清晰.风格良好.数据结构适当的C程序,从而具备解决综合性问题的能力.二、内容在熟练掌握C语言的基础知识:数据类型(整型.实型.字符型.指针.数组.结构等);运算类型(算术运算.逻辑运算.自增自减运算.赋值运算等);程序结构(顺序结构.判断选择结构.循环结构);大程序的功能分解方法(即函数的使用)等.进一步掌握各种函数的应用以及文件的读写操作等.三、实验任务:通讯录设计要求:实现菜单设计,使用数据文件保存和修改,应用结构体和指针功能要求:通讯录信息生成,存储,查询,修改,插入,删除,打印等.四、设计思路1.通讯录的主要信息包括:编号,姓名,性别,联系电话.住址,邮编.2.用结构体数组来存储信息,有Data_Input函数来实现信息的录入,用Data_Show函数来显示打印信息,用Data_Sreach函数来查找信息,用Data_Insert函数来插入信息,用Data_Alter 函数来修改信息,用Data_Delete函数来删除信息,用Data_Save函数来保存信息,用Exit函数来退出通讯录.3.小组分工,每个人分配几个函数,按情况进行分配任务.五、程序代码#include<string.h>/*字符函数和字符串函数*/#include<conio.h>/*字符模式函数(调用getch()函数)*/#include<stdio.h>/*输入输出函数*/int i;struct friend/*电子通讯录结构定义*/{char num[5]; /*编号*/char name[11]; /*名字*/char sex[2]; /*性别*/char phone[12]; /*电话*/char address[26]; /*地址*/char post_num[11]; /*邮编*/}friends[50];FILE *fp;void Data_load() /*数据载入函数*/{int j;fp=fopen("friend.txt","r+"); /*打开文件friend.txt*/ if(fp==NULL) /*判断是否存在friend.txt,如果不存在则创建*/{ fp=fopen("friend.txt","w");i=0;}else{for(i=0;i<50;i++){ j=fgetc(fp);if(j==EOF) /*判断是否到了文件尾*/return;fseek(fp,i*sizeof(struct friend),0);fread(&friends[i],sizeof(struct friend),1,fp); /*从文件中读取一条记录*/ }}}void Menu_Select() /*显示菜单界面*/{printf(" \n");printf(" \n");printf(" \n");printf(" Address Book Management System \n");printf(" \n");printf(" ======================\n");printf(" 1.Address book data Entry\n"); /*数据输入*/ printf(" 2.Address Book data Show\n"); /*数据显示*/ printf(" 3.Address Book data Search\n"); /*数据查找*/ printf(" 4.Address Book data Alter\n"); /*数据修改*/ printf(" 5.Address Book data Insert\n"); /*数据插入*/ printf(" 6.Address Book data Delete\n"); /*数据删除*/ printf(" 7.Address Book data Save\n"); /*数据保存*/ printf(" 0.Exit\n"); /*退出*/ printf(" ======================\n");printf( " Please chioce 0-7 \n\n");}int Data_check(int k,char ID[5]) /*检查通讯录中是否存在相同ID或ID输入格式错误*/ {int j;if(ID[0]=='0')k=1;for(j=0;ID[j]!='\0';j++){if(ID[j]>'9'||ID[j]<'0')k++;}for(j=0;j<i+1;j++){if(strcmp(ID,friends[j].num)==0)k++;}return k;}void Data_Input() /*数据输入函数*/ {char yes_no='1';char ID[5];int k=0;if(i>=50)printf("\n\n Storage full!\n\n");if(i<50){printf("************************************************************************\n"); printf(" ******************* Add Address Book Information***********************\n");printf("************************************************************************\n"); printf("************************************************************************\n");}for(;i<50;i++){do{switch(yes_no){case'1': /*如果输入为'1',则进行数据输入*/ printf(" ****** No.(4) Name(10) Sex(M/F) Phone(11) Address(25)Zip_Code(10)*******\n");scanf("%s%s%s%s%s%s",ID,friends[i].name,friends[i].sex,friends[i].phone,friends [i].address,friends[i].post_num);Data_check(k,ID);while(Data_check(k,ID)>0) /*检查输入的ID是否已存在,如果存在重新输入*/ {printf("The No. already exists Or The No. isn't correct, please re-enter\n");scanf("%s",ID);Data_check(k,ID);}strcpy(friends[i].num,ID);if(i<49){printf("\n\n Whether to be continue? Y(1)/N(0) \n\n");yes_no=getch();}if(i>=49)printf("\n\n Storage full!\n\n");break;case'0':break;default:yes_no=getch();}}while(yes_no!='1'&&yes_no!='0'); /*如果输入的不是'1'或'0'则重新输入*/ if(yes_no=='0') /*如果输入'0'则退出输入函数*/{i++;break;}}}int The_Size(char a[],char b[]) /*比较两个ID的大小*/ {int j,t;if((j=strlen(a)-strlen(b))>0) t=1;if((j=strlen(a)-strlen(b))<0) t=-1;if((j=strlen(a)-strlen(b))==0){if(strcmp(a,b)>0) t=1;if(strcmp(a,b)<0) t=-1;if(strcmp(a,b)==0) t=0;}return t;}void Data_Show() /*数据输出函数*/ {int j,k;char m;struct friend t;printf("********************************************************************\n");printf(" No. Name Sex Phone AddressZip_Code \n");printf("********************************************************************\n");for(j=0;j<i-1;j++) /*对数据进行排序*/ {for(k=0;k<i-1-j;k++){if(The_Size(friends[k].num,friends[k+1].num)==1){t=friends[k];friends[k]=friends[k+1];friends[k+1]=t;}}}for(j=0;j<i;j++) /*数据输出*/{printf("%4s %10s %4s %11s %20s %10s\n",friends[j].num,friends[j].name,friends[j ].sex,friends[j].phone,friends[j].address,friends[j].post_num);m=getch();if(m==’’)break;}printf("\n\n There are %d data in the book .\n\n",i); }void Data_Search() /*数据查找函数*/{char k;int j,a,b;char ID[5];char NAME[11];printf("Search by No. : 1\n");printf("Search by name : 2\n");k=getch();switch(k){case'1': /*按ID查找*/a=0;printf("\n\n Please enter the No.\n\n");scanf("%s",ID);for(j=0;j<i+1;j++){if(strcmp(ID,friends[j].num)==0){a++;printf(" No. Name Sex Phone Address Zip_Code \n");printf("%4s %10s %4s %11s %20s %10s\n",friends[j].num,friends[j].name,frien ds[j].sex,friends[j].phone,friends[j].address,friends[j].post_num);}}if(a==0)printf(" Do not have to find the No.!\n\n");break;case'2': /*按姓名查找*/b=0;printf("\n\n Please enter the Name\n\n");scanf("%s",NAME);for(j=0;j<i+1;j++){if(strcmp(NAME,friends[j].name)==0){b++;printf(" No. Name Sex Phone Address Zip_Code \n");printf("%4s %10s %4s %11s %20s %10s\n",friends[j].num,friends[j].name,friends[j ].sex,friends[j].phone,friends[j].address,friends[j].post_num);}}if(b==0)printf(" Do not have to find the Name!\n\n");break;default:printf("\n\n Error!\n");break;}}void Data_Insert() /*数据插入函数*/{if(i>=50)printf("\n\n Storage full!\n\n");if(i<50){char ID[5];int k=0;printf("Please enter the No. that you want to insert.\n");scanf("%s",ID);Data_check(k,ID);printf("%d",Data_check(k,ID)); /*检查所需插入的ID是否已存在,如果存在重新输入*/while(Data_check(k,ID)>0){printf("The No. already exists Or The No. isn't correct, pleasere-enter\n");scanf("%s",ID);Data_check(k,ID);}strcpy(friends[i].num,ID); /*插入数据*/ printf(" ****** Name(10) Sex(M/F) Phone(11) Address(30)Zip_Code(10)*******\n");scanf("%s%s%s%s%s",friends[i].name,friends[i].sex,friends[i].phone,friends[i].a ddress,friends[i].post_num);i++;}}void Data_Delete() /*数据删除函数*/{int k,t=0;char ID[5];printf("\n\n Please enter the No. need to be deleted\n\n");scanf("%s",ID);for(k=0;k<i;k++){if(strcmp(friends[k].num,ID)==0){t++;break;}}if(t==0)printf("\n\n The No. does not Exist!\n\n");if(t>0){for(;k<i;k++) /*删除位置前的元素顺序前移*/{friends[k]=friends[k+1];}printf("\n\n Delete success!\n\n");i=i-1;}}void Data_Alter() /*修改函数*/{int k,t=0;char ID[5];printf("\n\n Please enter the No. to be Amended\n\n");scanf("%s",ID);for(k=0;k<i;k++){if(strcmp(friends[k].num,ID)==0){t++;break;}}if(t==0)printf("\n\n The No. does not Exist!\n\n");if(t>0){strcpy(friends[k].num,ID);printf(" ****** Name(10) Sex(M/F) Phone(11) Address(30)Zip_Code(10)*******\n");scanf("%s%s%s%s%s",friends[k].name,friends[k].sex,friends[k].phone,friends[k].a ddress,friends[k].post_num);printf("\n\n Alter Success!\n\n");}}void Data_Save() /*数据保存函数*/{int j;fp=fopen("friend.txt","w");for(j=0;j<=i-1;j++){fwrite(&friends[j],sizeof(struct friend),1,fp);}printf("\n\n Save Success!\n\n");}void Exit() /*退出函数*/{char flag;printf(" Save or Not? (Y/N)\n"); /*判断是否保存*/do{flag=getch();switch(flag){case'Y': /*保存*/Data_Save();break;case'y': /*保存*/Data_Save();break;case'N':break;case'n':break;}}while(flag!='Y'&&flag!='y'&&flag!='N'&&flag!='n');}void main(){char choose,yes_no;Data_load();do{Menu_Select();choose=getch();switch(choose){case'1': Data_Input(); break; /*输入*/case'2': Data_Show(); break; /*显示*/case'3': Data_Search(); break; /*查找*/case'4': Data_Alter(); break; /*修改*/case'5': Data_Insert(); break; /*插入*/case'6': Data_Delete(); break; /*删除*/case'7': Data_Save(); break; /*保存*/case'0': Exit(); break; /*退出*/default : printf(" Error!\n");}if(choose=='0')break;printf(" Would you like to be continue? (Y/N)\n");do{yes_no=getch();}while(yes_no!='Y'&&yes_no!='y'&&yes_no!='N'&&yes_no!='n');if(yes_no=='N'||yes_no=='n'){Exit();break;}}while(yes_no!='Y'||yes_no!='y');六、函数说明本人所写函数为: Data_check , Data_Input, The_Size, Data_Show,main.以下为各函数的功能说明,代码以及流程图:Data_check:本函数的功能是判断输入的编号是否以存在及格式是否正确.首先定义一个整型形参,一个字符数组形参.首先判断编号的首位是否为0,如果为0则整型形参赋值为1.反之没有动作,然后判断编号内是否含义字母及其他字符,如果有则整型形参自增,反之没有动作,在使用strcmp判断输入的编号在原文件中是否以存在,如果存在则整型形参自增.最后返回整型形参的值.源代码:/*检查通讯录中是否存在相同ID或ID输入格式错误*/int Data_check(int k,char ID[5]){int j;if(ID[0]=='0')k=1;for(j=0;ID[j]!='\0';j++){if(ID[j]>'9'||ID[j]<'0')k++;}for(j=0;j<i+1;j++){if(strcmp(ID,friends[j].num)==0)k++;}return k;}流程图:Data_Input:首先判断储存是否已满,如果满了,则提示是否回到主菜单,如果没满,则提输入信息,然后调用Data_check函数,判断编号是否已经存在以及格式是否正确.如果均无误则提示是否继续输入信息,反之则重新输入编号直到编号无误为止.如果输入信息后,储存变满,则提示储存已满,不再提示是否继续输入.最后提示是否回到主菜单.源代码:void Data_Input() /*数据输入函数*/{char yes_no='1';char ID[5];int k=0;if(i>=50)printf("\n\n Storage full!\n\n");if(i<50){printf("************************************************************************\n"); printf(" ******************* Add Address Book Information***********************\n");printf("************************************************************************\n"); printf("************************************************************************\n");}for(;i<50;i++){do{switch(yes_no){case '1': /*如果输入为'1',则进行数据输入*/printf(" ****** No.(4) Name(10) Sex(M/F) Phone(11) Address(25)Zip_Code(10)*******\n");scanf("%s%s%s%s%s%s",ID,friends[i].name,friends[i].sex,friends[i].phone,friends [i].address,friends[i].post_num);Data_check(k,ID);while(Data_check(k,ID)>0) /*检查输入的ID是否已存在,如果存在重新输入*/{printf("The No. already exists Or The No. isn't correct, please re-enter\n");scanf("%s",ID);Data_check(k,ID);}strcpy(friends[i].num,ID);if(i<49){printf("\n\n Whether to be continue? Y(1)/N(0) \n\n");yes_no=getch();}if(i>=49)printf("\n\n Storage full!\n\n");break;case '0':break;default:yes_no=getch();}}while(yes_no!='1'&&yes_no!='0'); /*如果输入的不是'1'或'0'则重新输入*/ if(yes_no=='0') /*如果输入'0'则退出输入函数*/{i++;break;}}}流程图:The_Size:首先定义两个字符数组形参,一个整型变量.首先利用strlen比较两个字符数组的长度,如果前者长于后者,整型变量赋值为1如果前者短于后者,整型变量赋值为-1,如果两者长度相等,则再利用strcmp比较两个字符数组的大小,如果前者大于后者,则整型变量赋值为1,如果前者小于后者,则整型变量赋值为-1,如果两者大小相等,则整型变量赋值为0.最后返回整型变量的值.源代码:int The_Size(char a[],char b[]) /*比较两个ID的大小*/{int j,t;if((j=strlen(a)-strlen(b))>0) t=1;if((j=strlen(a)-strlen(b))<0) t=-1;if((j=strlen(a)-strlen(b))==0){ if(strcmp(a,b)>0) t=1;if(strcmp(a,b)<0) t=-1;if(strcmp(a,b)==0) t=0;}return t; }流程图:Data_Show:首先调用The_Size函数再利用冒泡法对通讯录的信息根据编号进行排列.然后再对信息进行输出,输出完一条信息后按空格停止打印,按其他任意键继续打印下一条.然后输出通讯录中信息的条数,最后提示是否回到主菜单源代码:void Data_Show() /*数据输出函数*/{ int j,k;char m;struct friend t;printf("********************************************************************\n");printf(" No. Name Sex Phone Address Zip_Code \n");printf("********************************************************************\n");for(j=0;j<i-1;j++) /*对数据进行排序*/{ for(k=0;k<i-1-j;k++){ if(The_Size(friends[k].num,friends[k+1].num)==1){ t=friends[k];friends[k]=friends[k+1];friends[k+1]=t;}}}for(j=0;j<i;j++) /*数据输出*/{ printf("%4s %10s %4s %11s %20s %10s\n",friends[j].num,friends[j].name,frien ds[j].sex,friends[j].phone,friends[j].address,friends[j].post_num);m=getch();if(m==' ')break;}printf("\n\n There are %d data in the book .\n\n",i);} 流程图:main:调用Menu_Selec函数打印出主菜单.利用switch实现对菜单功能的选择.利用do-while来实现功能选择是输入不正确的纠错.源代码:void main(){char choose,yes_no;Data_load();do{Menu_Select();choose=getch();switch(choose){case'1': Data_Input(); break; /*输入*/case'2': Data_Show(); break; /*显示*/case'3': Data_Search(); break; /*查找*/case'4': Data_Alter(); break; /*修改*/case'5': Data_Insert(); break; /*插入*/case'6': Data_Delete(); break; /*删除*/case'7': Data_Save(); break; /*保存*/case'0': Exit(); break; /*退出*/default : printf(" Error!\n");}if(choose=='0')break;printf(" Would you like to be continue? (Y/N)\n");do{yes_no=getch();}while(yes_no!='Y'&&yes_no!='y'&&yes_no!='N'&&yes_no!='n');if(yes_no=='N'||yes_no=='n'){Exit();break;}}while(yes_no!='Y'||yes_no!='y');流程图:七、程序调试1.启动程序2.输入数据3.显示数据4.查找数据6.插入数据8.保存数据9.退出八、实验心得C语言是国内外广泛使用的计算机语言,学会、学好、使用C语言进行程序设计是时代的要求,也是计算机工作者的一项基本功。