C语言 电话簿管理系统VC++6.0运行通过.doc
/*电话簿管理系统*/the telephon management system/created by tengzhenfang/data:2010.12.24/*/#include<stdio.h>#include<stdlib.h>#include<string.h>#include<conio.h>/*预定义*/#define HEADER1 "-TELEPHONE BOOK-n"#define HEADER2 "| num | name | phonenumber | address |n"#define HEADER3 "|-|-|-|-|n"#define FORMAT " %-10s | %-10s | %-15s | %-20s |n"#define DATA p->num,p->name,p->phonenum,p->address#define END "-n"#define N 100/*定义全局变量*/int saveflag=0; /是否需要存盘的标志变量/*定义系统的数据结构-电话簿相关信息组成的结构体*/typedef struct telebookint num; /编号char name15; /姓名char phonenum15; /电话号码char address20; /地址TELEBOOK;/*用户自定义函数原型说明*/void menu();void Disp(TELEBOOK temp,int n);void Wrong();int Add(TELEBOOK temp,int n);void Qur(TELEBOOK temp,int n);int Del(TELEBOOK temp,int n);void Modify(TELEBOOK temp,int n);int Insert(TELEBOOK temp,int n);void SelectSort(TELEBOOK temp,int n);void Save(TELEBOOK temp,int n);/*主函数*/void main()TELEBOOK teleN; /定义了N条电话簿记录FILE *fp; /定义文件指针int select; /保存选择结果变量char ch; /保存(y,Y,n,N)int count=0;fp=fopen(".telephonebook4.dat","ab+");/以追加方式打开二进制文件 c:telephonebook4.data,可读可写,若此文件不存在,则会自动创建此文件if(fp=NULL)printf("n=>can not open file!n");exit(0); /程序退出函数,exit(0)为正常退出,在头文件 stdlib.h 里while(!feof(fp)if(fread(&telecount,sizeof(TELEBOOK),1,fp)=1) /一次从文件读取一条电话簿记录count+;fclose(fp); /关闭文件printf("n=>open file success,the total records number is :%d.n",count);getchar();/menu();while(1)system("cls");menu();printf("n Please Enter your choice(09):");scanf("%d",&select);if(select=0)if(saveflag=1) /对数组的数据有修改且未存盘fflush(stdin);getchar();printf("n=>Whether save the modified record to file?(y/n):");scanf("%c",&ch);if(ch='y'|ch='Y')Save(tele,count); /保存记录至文件printf("n=>thank you for useness!");fflush(stdin);getchar();break;switch(select)case 1:count=Add(tele,count); /增加电话簿记录 break; case 2:system("cls"); Disp(tele,count); /显示电话簿记录 break;case 3:count=Del(tele,count); /删除电话簿记录 break;case 4:Qur(tele,count); /查询电话簿记录 break;case 5:Modify(tele,count); /修改电话簿记录 break;case 6:count=Insert(tele,count); /插入电话簿记录 break;case 7:SelectSort(tele,count); /排序电话簿记录 break;case 8:Save(tele,count); /保存电话簿记录 break;default:Wrong(); fflush(stdin); getchar(); /按键有误,必须为数值09 break; /*主菜单界面*/用户进入电话簿管理系统时,需要显示主菜单,提示用户进行选择,完成相应任务。此函数被主函数调用。/*/void menu()system("cls"); /清屏,与clrscr()功能相同printf(" The telephone-book Management System n");printf("*Menu*n");printf(" * 1 input record 2 display record *n");printf(" * 3 delete record 4 search record *n");printf(" * 5 modify record 6 insert record *n");printf(" * 7 sort record 8 save record *n");printf(" * 0 quit system n");printf("*n");/*显示电话簿记录*/显示从数组temp第一个元素开始的n条记录/*/输出表格头部,单独在一个函数里实现void printheader()printf("-TELEPHONE BOOK-n");printf("| num | name | phonenumber | address |n");printf("|-|-|-|-|n");void Disp(TELEBOOK temp,int n)int i;if(n=0)printf("n=>Not telephone record!n");fflush(stdin);getchar();return;printf("nnnn");printheader(); /输出表格的头部for(i=0;i<n;i+) /逐条输出数组中存储的电话簿记录printf("|%-10d|%-15s|%-15s|%-20s|n",tempi.num,tempi.name,tempi.phonenum,tempi.address);printf("|-|-|-|-|n");fflush(stdin);getchar();/*输出按键错误信息*/void Wrong()printf("n*Error:input has wrong!press any key to continue*n");fflush(stdin);getchar();/*增加电话簿记录*/调用Add(TELEBOOK temp,int n)函数,完成在数组temp中添加电话簿记录的功能。/在刚进入电话簿管理系统时,若默认的数据文件为空,则从数组的头部开始增加记录;/否则,将此记录添加在数组的尾部。/*/专门的字符串输入函数,减少代码的重复率void stringinput(char *t,int lens,char *notice)char n255;doprintf(notice);scanf("%s",n);if(strlen(n)>=lens)printf("n长度超出,请重新输入。n");while(strlen(n)>=lens);strcpy(t,n); /将输入的字符串拷贝到字符串t中/int Add(TELEBOOK temp,int n)int number;int i=0;/char ch20;int flag=0;char ch1;Disp(temp,n); /先打印出已有的电话簿记录/printf("请输入增加的电话簿的编号:n");while(1)while(1)printf("请输入增加的电话簿的编号:n");scanf("%d",&number);if(number=0)return n;while(i<n)if(tempi.num=number)flag=1;break;i+;if(flag=1)printf("此编号已经存在,是否继续增加?(y/n:)");fflush(stdin);scanf("%c",&ch1);if(ch1='y'|ch1='Y')continue;elsereturn n;elsebreak;tempn.num=number;/在输入姓名、电话号码、地址的时候,输入的都是字符串,而且都要判断长度超出的情况,为了/减少代码重复率,专门编写一个输入字符串的函数,通过调用这个函数实现字符串的输入。/*printf("请输入姓名:");while(1)scanf("%s",ch);if(strlen(ch)>=15)printf("长度超出,请重新输入.n");elsebreak;strcpy(tempn.name,ch);printf("请输入电话号码:");while(1)scanf("%s",ch);if(strlen(ch)>=15)printf("长度超出,请重新输入.n");elsebreak;strcpy(tempn.phonenum,ch);printf("请输入地址:");while(1)scanf("%s",ch);if(strlen(ch)>=20)printf("长度超出,请重新输入.n");elsebreak;strcpy(tempn.address,ch);*/stringinput(tempn.name,15,"请输入姓名");stringinput(tempn.phonenum,15,"请输入电话号码:");stringinput(tempn.address,20,"请输入地址:");saveflag=1;n+; return n;/*记录查找定位函数*/在对记录进行查询、修改、删除的时候,都要进行记录的定位操作,因此,将/记录的定位操作作为一个单独的函数进行处理,这样可以节省代码率,优化代码质量/以下Locate()函数完成了记录的查找定位功能,可以按联系人查找或者按电话号码查找/findmess保存要查找的具体内容,nameorphonenum保存按什么在数组中查找/*/int Locate(TELEBOOK temp,int n,char findmess,char nameorphonenum)int i=0;/printf("%s %sn",nameorphonenum,findmess);if(strcmp(nameorphonenum,"phonenum")=0) /按电话号码查询for(i=0;i<n;i+)if(strcmp(tempi.phonenum,findmess)=0)return i;else if(strcmp(nameorphonenum,"name")=0) /按姓名查询for(i=0;i<n;i+)if(strcmp(tempi.name,findmess)=0)return i; return -1; /若未找到,则返回-1/*查询电话簿记录*/调用Qur(TELEBOOK temp,int n)函数,完成在数组temp中查询电话簿记录的功能。/当用户执行查询任务时,系统会提示用户进行查询字段的选择,即根据联系人姓名或电话/号码进行查询。若此记录存在,则会以表格形式打印输出此条记录信息。/*/void Qur(TELEBOOK temp,int n)int select; /1,按姓名查询 2 按电话号码查询 其他,返回主界面char ch20; /保存用户输入的查询内容int p;if(n=0) /若数组为空printf("n=>Not telephone record!n");fflush(stdin);getch();return;printf("n => 1 Search by name => 2 Search by telephone numbern");printf("Please choice1,2:");scanf("%d",&select);if(select=1) /按姓名查询stringinput(ch,15,"请输入要查询的姓名:");p=Locate(temp,n,ch,"name"); /利用Locate函数查找符合ch内容的记录,并将记录的下标返回if(p!=-1)printheader();printf("|%-10d|%-15s|%-15s|%-20s|n",tempp.num,tempp.name,tempp.phonenum,tempp.address);printf("|-|-|-|-|n");printf("press any key to return ");getch();elseprintf("The record is not foundn");getch();else if(select=2) /按电话号码查询stringinput(ch,15,"请输入要查询的电话号码:");p=Locate(temp,n,ch,"phonenum"); /利用Locate函数查找符合ch内容的记录,并将记录的下标返回if(p!=-1)printheader();printf("|%-10d|%-15s|%-15s|%-20s|n",tempp.num,tempp.name,tempp.phonenum,tempp.address);printf("|-|-|-|-|n");printf("press any key to return ");getch();elseprintf("The record is not foundn");getch();elseWrong();getch();/*删除电话簿记录*/调用Del(TELEBOOK temp,int n)函数删除电话簿记录的功能。可以根据/电话簿姓名删除,也可以按电话号码删除。/*/int Del(TELEBOOK temp,int n)int select;char ch20,ch0;int p,i;if(n=0)printf("n=>no telephone num record.n");getch();return n;printf("删除之前的电话簿记录为:n");Disp(temp,n);printf("n=>1 DElete by name =>2 Delete by phonen");scanf("%d",&select);if(select=1) /按姓名删除stringinput(ch,15,"请输入要删除的电话簿记录的姓名:");p=Locate(temp,n,ch,"name");if(p!=-1)printf("n要删除的电话簿记录为:n");printheader();printf("|%-10d|%-15s|%-15s|%-20s|n",tempp.num,tempp.name,tempp.phonenum,tempp.address);printf("n确认要删除?y/n:");fflush(stdin);scanf("%c",&ch0);if(ch0='y'|ch0='Y')for(i=p+1;i<n;i+)tempi-1=tempi;n-;printf("nDeleted success!n");saveflag=1;getch();elsegetch();return n;elseprintf("n所删除的联系人不存在.n");getch();else if(select=2)stringinput(ch,15,"请输入要删除的电话簿记录的电话号码:");p=Locate(temp,n,ch,"phonenum");if(p!=-1)printf("n要删除的电话簿记录为:n");printheader();printf("|%-10d|%-15s|%-15s|%-20s|n",tempp.num,tempp.name,tempp.phonenum,tempp.address);for(i=p+1;i<n;i+)tempi-1=tempi;n-;printf("nDeleted success!n");saveflag=1;getch();elseprintf("n所删除的联系人不存在.n");getch();else Wrong();return n;/*修改电话簿记录*/调用Modify(TELEBOOK temp,int n)函数完成修改电话簿记录的功能/先按联系人对电话簿记录进行定位查找,然后提示用户修改除编号之外的/的其他值,记录编号不能修改/*/void Modify(TELEBOOK temp,int n)char ch20;int p;if(n=0)printf("n=>no telephone num record.n");getch();return ;stringinput(ch,15,"请输入要查找的联系人姓名:");p=Locate(temp,n,ch,"name");if(p!=-1)printf("修改前的联系人的信息为:n");printheader();printf("|%-10d|%-15s|%-15s|%-20s|n",tempp.num,tempp.name,tempp.phonenum,tempp.address);printf("n请输入要修改的联系人的相关信息:n");stringinput(tempp.name,15,"请输入修改后的姓名:");stringinput(tempp.phonenum,15,"请输入修改后的电话号码:");stringinput(tempp.address,20,"请输入修改后的地址:");saveflag=1;elseprintf("您所要修改的联系人不存在,请返回。");getch();/*插入电话簿记录*/调用Insert(TELEBOOK temp,int n)函数,完成在数组temp中插入电话簿记录的/功能。在插入记录操作中,系统会先按记录编号查找到要插入的元素的位置,然后/在该记录编号处插入一个新记录。/*/int Insert(TELEBOOK temp,int n)int number,i;int flag=0,k;char ch;TELEBOOK newrecord;Disp(temp,n);while(1)printf("n请输入要插入的记录的编号:");scanf("%d",&number);for(i=0;i<n;i+)if(tempi.num=number)flag=1;break;if(flag=1)printf("编号已经存在,是否要重新输入(y/n):");fflush(stdin);scanf("%c",&ch);if(ch='y'|ch='Y')continue;elsereturn n;elsebreak;for(i=0;i<n;i+) /按编号的先后顺序,找到编号应该插入的位置,为下标kif(number<tempi.num)break;k=i;for(i=n-1;i>=k;i-) /从下标 k 开始元素逐个后移tempi+1=tempi;printf("请输入要插入的新记录的信息:n");newrecord.num=number;stringinput(newrecord.name,15,"请输入姓名:");stringinput(newrecord.phonenum,15,"请输入电话号码:");stringinput(newrecord.address,20,"请输入地址:");tempk=newrecord;n+;saveflag=1;printf("插入记录成功!n");Disp(temp,n);getch();return n;/*对电话簿记录进行排序*/调用SelectSort(TELEBOOK temp,int n)函数,利用选择排序法完成对电话簿/记录的排序操作,可以按照编号排序,或者按照姓名排序/*/void SelectSort(TELEBOOK temp,int n)int select,k,i,j;TELEBOOK tt;if(n=0)printf("n=>No telephone record !n");getch();return ;printf("排序前的电话簿记录为:n");Disp(temp,n);printf("=>1 sort by number =>2 sort by namen");printf("请选择排序方式:n");scanf("%d",&select);if(select=1)for(i=0;i<n-1;i+)k=i;for(j=i+1;j<n;j+)if(tempj.num<tempk.num)k=j;tt=tempi;tempi=tempk;tempk=tt;printf("排序成功!n");saveflag=1;printf("排序后的电话簿记录为:n");Disp(temp,n);return;else if(select=2)for(i=0;i<n-1;i+)k=i;for(j=i+1;j<n;j+)if(strcmp(tempj.name,tempk.name)<0)k=j;tt=tempi;tempi=tempk;tempk=tt;printf("排序成功!n");saveflag=1;printf("排序后的电话簿记录为:n");Disp(temp,n);return;elseWrong();/*对电话簿记录进行存储*/调用Save(TELEBOOK temp,int n)函数,完成电话簿记录的存盘操作。系统会将数组中的数据/写入至磁盘文件,若用户对数据修改后没有存盘,则在退出系统时,会提醒用户是否要存盘。/*/void Save(TELEBOOK temp,int n)FILE *fp;int i;fp=fopen(".telephonebook4.dat","wb"); /以只写方式打开二进制文件,若if(fp=NULL)printf("n=>open file failed!n");getch();return;for(i=0;i<n;i+)if(fwrite(&tempi,sizeof(TELEBOOK),1,fp)=1) /每次写一条记录或者一个结构体数组至文件continue;elsebreak;if(i>0)