使用双向链表实现通讯录,实现添加功能、删除功能、查询功能、修改功能、显示功能。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct linkman
{
char name[10];
char Tel[20];
struct linkman *prev;
struct linkman *next;
}linkman;
int Menu(void);//主菜单
int menu2(void);
void InitList(struct linkman **head);//初始化链表
void Readfile(linkman *head);//从文件中读数据
void Writefile(linkman *head);//往文件中写数据
void Add(struct linkman *head);
void Add_one(struct linkman *head,char *name,char *Tel);
void Delete(struct linkman *head);
linkman *Search(struct linkman *head,char message[]);
linkman *Search_name(struct linkman *head,char message[]);
linkman *Search_tel(struct linkman *head,char message[]);
void GoSearch(struct linkman *head,struct linkman *p);
void Change(struct linkman *head);
void Print(struct linkman *head);//输出整个通讯录
void print(struct linkman *p);//输出查询出的单个联系人的信息
void Shifang(struct linkman *head);//释放所有节点
void main()
{
struct linkman *address_list=NULL,*p=NULL;
InitList(&address_list);
Readfile(address_list);
int num;
char message[20];
while(1)
{
num=Menu();
switch(num)
{
case 1:Add(address_list);
printf("\n");
break;
case 2:Delete(address_list);
printf("\n");
break;
case 3:getchar();//把上一个输入的换行读入缓冲区,避免message读入
printf("请输入要查找的联系人姓名或电话:");
scanf("%s",message);
p=Search(address_list,message);
if(p)
{
print(p);
GoSearch(address_list,p);
}
else
printf("此联系人不存在!\n");
printf("\n");
break;
case 4:Change(address_list);
printf("\n");
break;
case 5:Print(address_list);
printf("\n");
break;
case 0:Writefile(address_list);
printf("已退出通讯录!\n");
Shifang(address_list);
exit(0);
printf("\n");
default:printf("error!\n");
}
}
}
void Readfile(linkman *head)
{
linkman *p=NULL;
char name[10],Tel[20];
FILE *fp=fopen("address_book.txt","r");
fscanf(fp,"%s%s",name,Tel);
while(!feof(fp))
{
printf("%s %s\n",name,Tel);
Add_one(head,name,Tel);
fscanf(fp,"%s%s",name,Tel);
}
fclose(fp);
}
void Writefile(linkman *head)
{
linkman *p=head->next;
FILE *fp=fopen("address_book.txt","w");
for(;p!=head;p=p->next)
{
fwrite(p->name,strlen(p->name),1,fp);
fputs(" ",fp);
fwrite(p->Tel,strlen(p->Tel),1,fp);
fputs("\n",fp);
}
fclose(fp);
}
int Menu(void)
{
int choice;
printf(" 通讯录\n");
printf("**************************************\n");
printf("1.添加联系人\n");
printf("2.删除联系人\n");
printf("3.查找联系人\n");
printf("4.编辑联系人\n");
printf("5.显示所有联系人\n");
printf("0.退出\n");
printf("**************************************\n");
printf("Please enter your choice:");
scanf("%d",&choice);
return choice;
}
int menu2(void)
{
int num;
printf("1.查看上一个联系人\n");
printf("2.查看下一个联系人\n");
printf("0.退出查询\n");
printf("请输入你的选择:");
scanf("%d",&num);
return num;
}
void InitList(struct linkman **head)
{
while((*head)==NULL)
{
*head=(struct linkman *)malloc(sizeof(struct linkman));
}
(*head)->next=(*head);
(*head)->prev=(*head);
}
void Add(struct linkman *head)
{
char name[10];
char Tel[20];
char choice;
linkman *p=NULL,*q=NULL;
printf("请输入联系人的姓名:");
scanf("%s",name);
printf("请输入联系人的电话:");
scanf("%s",Tel);
q=Search(head,name);
if(q)
{
getchar();//把上一个输入的换行读入缓冲区,避免name读入
while(1)
{
printf("此联系人已存在,是否替换(Y/N):");
scanf("%c",&choice);
if(choice=='Y'||choice=='y')
{
strcpy(q->name,name);
strcpy(q->Tel,Tel);
printf("添加成功!\n");
break;
}
else if(choice=='N'||choice=='n')
{
printf("取消添加!\n");
break;
}
else
continue;//若输入非'Y'、'N'的字符就继续询问
}
}
else
{
Add_one(head,name,Tel);
printf("添加成功!\n");
}
}
void Add_one(struct linkman *head,char *name,char *Tel)
{
linkman *p=NULL;
while(!p)
{
p=(struct linkman *)malloc(sizeof(struct linkman));
}
strcpy(p->name,name);
strcpy(p->Tel,Tel);
//使用前插法插入新节点
head->prev->next=p;
p->prev=head->prev;
p->next=head;
head->prev=p;
}
void Delete(struct linkman *head)
{
linkman *p=head;
char name[10];
char choice;
printf("请输入要删除的联系人姓名:");
scanf("%s",name);
p=Search_name(head,name);
if(p)
{
print(p);
getchar();//把上一个输入的换行读入缓冲区,避免choice读入
while(1)
{
printf("是否删除此联系人(Y/N):");
scanf("%c",&choice);
if(choice=='Y'||choice=='y')
{
p->prev->next=p->next;
p->next->prev=p->prev;
free(p);
printf("删除成功!\n");
break;
}
else if(choice=='N'||choice=='n')
{
printf("取消删除!\n");
break;
}
else
continue;//若输入非'Y'、'N'的字符就继续询问
}
}
else
printf("此联系人不存在!\n");
}
linkman *Search(struct linkman *head,char message[])
{
linkman *p=head;
p=Search_name(head,message);
if(p)
return p;
p=Search_tel(head,message);
if(p)
return p;
return NULL;
}
linkman *Search_name(struct linkman *head,char message[])
{
linkman *p=head;
if(p->next!=head)
{
while(p->next!=head)
{
p=p->next;
if(strcmp(p->name,message)==0)
return p;
}
}
return NULL;
}
linkman *Search_tel(struct linkman *head,char message[])
{
linkman *p=head;
if(p->next!=head)
{
while(p->next!=head)
{
p=p->next;
if(strcmp(p->Tel,message)==0)
return p;
}
}
return NULL;
}
void GoSearch(struct linkman *head,struct linkman *p)
{
int num;
while(1)
{
num=menu2();
switch(num)
{
case 1:p=p->next;
if(p==head)
p=p->next;
print(p);
break;
case 2:p=p->prev;
if(p==head)
p=p->next;
print(p);
break;
case 0:printf("已退出查询!\n");
return;
default:printf("error!\n");
break;
}
}
}
void Change(struct linkman *head)
{
linkman *p=NULL,*q=NULL;
char name[10],choice;
printf("请输入要编辑的联系人姓名:");
scanf("%s",name);
p=Search_name(head,name);
int num;
if(p)
{
print(p);
printf("1.编辑姓名\n");
printf("2.编辑电话\n");
printf("0.取消编辑\n");
printf("请输入你的选择:");
scanf("%d",&num);
switch(num)
{
case 1:printf("请输入修改后的姓名:");
scanf("%s",name);
while(1)
{
q=Search(head,name);
if(q)
{
printf("此联系人已存在,是否继续修改(Y/N):");
getchar();
scanf("%c",&choice);
if(choice=='Y'||choice=='y')
{
printf("请输入修改后的姓名:");
scanf("%s",name);
}
else if(choice=='N'||choice=='n')
{
printf("已取消修改!\n");
break;
}
else
continue;
}
else
{
strcpy(p->name,name);
printf("修改成功!\n");
break;
}
}
break;
case 2:printf("请输入修改后的电话:");
scanf("%s",p->Tel);
printf("修改成功!\n");
break;
case 0:printf("已取消修改!\n");
break;
default:printf("error!\n");
}
}
else
printf("此联系人不存在!\n");
}
void Print(struct linkman *head)
{
linkman *p=head;
if(p->next==head)
printf("通讯录为空!\n");
else
{
printf("*-----------------------------------*\n");
printf(" 姓名 电话\n\n");
while(p->next!=head)
{
p=p->next;
printf("%10s %s\n",p->name,p->Tel);
}
printf("*-----------------------------------*\n");
}
}
void print(struct linkman *p)
{
printf("*-----------------------------------*\n");
printf(" 姓名 电话\n\n");
printf("%10s %s\n",p->name,p->Tel);
printf("*-----------------------------------*\n");
}
void Shifang(struct linkman *head)
{
linkman *p=head;
if(p->next!=head)
{
p=p->next;//释放掉头结点后面的那个节点
p->prev->next=p->next;
p->next->prev=p->prev;
free(p);
p=head;
}
free(p);//释放掉头结点
}
在相同目录下建立一个名为“address_book.txt”的txt文件,里面可以先写几个联系人的信息,中间用空格隔开。例如