C語言使用雙向循環鏈表實現通訊錄

使用雙向鏈表實現通訊錄,實現添加功能、刪除功能、查詢功能、修改功能、顯示功能。

#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文件,裏面可以先寫幾個聯繫人的信息,中間用空格隔開。例如
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章