链表之通讯录

链表通讯录(带文件保存)

 

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

struct node
{
	char name[15];
	char loc[30];
	int num;
	int tel;

	struct node * next;
}po;

typedef struct node Node;
typedef struct node * Link;


void create_new_node(Link *new_node)
{
	*new_node = (Link)malloc(sizeof(Node));
	if(*new_node == NULL)
	{
		printf("创建失败!\n");
		exit(-1);
	}
}

void create_head(Link *head)
{
	create_new_node(head);
	(*head) -> next = NULL;                      //带表头链表
}


int  show()
{
	int n;
	printf("\
              ********************\n\
              *          欢迎使用通讯录!          *\n\
              *  1* 添加联系人      2* 编辑联系人  *\n\
              *  3* 查看联系人      4* 查找联系人  *\n\
              *  5* 联系人总数      6* 删除联系人  *\n\
              *  7* 排序方式        8* 清空联系人  *\n\
              *  9* 删除重复联系人  10*打开通讯录  *\n\
              *  0* 退出                           *\n\
              ********************\n");
	printf("请输入要选择的功能:\n");
	scanf("%d",&n);
	getchar();
	if(n < 0 || n > 11)
		printf("输入错误!!\n");
	else
		return n;

}

void insert_tail(Link head,Link new_node)
{
	Link p = head;
	while(p -> next != NULL)
	{
		p = p -> next;
	}
	p -> next = new_node;
	new_node -> next = NULL;
}

void add(Link head)
{
	int i = 1;
	Link new_node = NULL;
	printf("请依次输入联系人的姓名、电话和所在地:\n");
	while(1)
	{
		create_new_node(&new_node);
		printf("请输入第%d个联系人信息(q退出)!\n",i);
		scanf("%s",new_node -> name);
		if(strcmp(new_node -> name,"q") == 0)                       //设置q退出
			break;
		scanf("%d",&new_node -> tel);
		scanf("%s",new_node -> loc);
		i++;
		insert_tail(head,new_node);

	}
}

void display1(Link head)
{
	int i = 1;
	Link p = head -> next;
	if(head -> next == NULL)
		printf("联系人列表为空!\n");
	else
	{
		printf("\
序号  姓名         手机号                  归属地\n");
		while(p != NULL)
		{
			p -> num = i;
			printf("%-6d",p -> num);
			printf("%-13s",p -> name);
			printf("%-24d",p -> tel);
			printf("%-30s\n",p -> loc);
			i++;
			p = p -> next;
		}
		printf("--------------------------------------------------------------------\n");
	}
}

Link search(Link head)
{
	int i,j = 0;
	char name[10];
	char loc[30];
	int tel;
	Link p = head -> next;
	int n;
	if(p == NULL)
		printf("当前通讯录列表为空!!!\n");
	else
	{
	printf("请选择要搜索的方式(0退回主菜单):\n\
1、姓名查找\n\
2、号码查找\n\
3、归属地查找\n");
	scanf("%d",&n);
	getchar();
	if(n < 0 || n > 3)
	{
		printf("输入错误!!\n");return;
	}
	else
	{
		switch(n)
		{
			case 0:break;
			case 1:
   				   {
   					   printf("请输入你要搜索联系人的姓名:\n");
					   scanf("%s",name);
					   while(p != NULL)
					   {
  						   if(strcmp(p -> name,name) == 0)
						   {
		printf("\
姓名         手机号                  归属地\n");
   		               printf("%-13s",p -> name);
					   printf("%-24d",p -> tel);
					   printf("%-30s\n",p -> loc);
  						   j++;
						   }
						   p = p -> next;
					   }
					   if(j == 0)
						   printf("没有搜索到此联系人!\n");
					   break;
				   }
					  
			case 2:
 				   {
 					   printf("请输入要搜索的号码:\n");
					   scanf("%d",&tel);
					   while(p != NULL)
					   {
 						   if(tel - p -> tel == 0)
					       {
		printf("\
姓名         手机号                  归属地\n");
  	 	                   printf("%-13s",p -> name);
						   printf("%-24d",p -> tel);
						   printf("%-30s\n",p -> loc);
						   j++;
						   }
						   p = p -> next;
					   }
					   if(j == 0)
						   printf("没有搜索到此联系人!\n");
	 				   break;

				   }
			case 3:{
  					   printf("请输入你要搜索联系人的归属地:\n");
					   scanf("%s",loc);
					   while(p != NULL)
					   {
	 					   if(strcmp(p -> loc,loc) == 0)
						   {
		printf("\
姓名         手机号                  归属地\n");
  	 	               printf("%-13s",p -> name);
					   printf("%-24d",p -> tel);
					   printf("%-30s\n",p -> loc);
 	 					   j++;
						   }
						   p = p -> next;
					   }
					   if(j == 0)
						   printf("没有搜索到此联系人!\n");
					   break;
				   }
			default:{printf("请重新输入正确选项!\n");search(head);break;}
		}
	}
	}
}

void clear(Link head)
{
	Link q = head;
	Link p = head -> next;
	if(p == NULL)
		printf("联系人列表为空无需清空!\n");
	else
	{
		while(p != NULL)
		{
			head -> next = p -> next;
			q = p -> next;
			free(p);
			p = q;
		}
		printf("恭喜!清空完成!\n");

	}
}

void len(Link head)
{
	int i = 0;
		Link p = head;
	while(p -> next != NULL)
	{
		p = p -> next;
		i++;
	}
	printf("当前通讯录有%d个联系人!\n",i);

}

void edit(Link head)
{
	int n, j = 0;
	char name[10];
	Link p = head -> next;
	if(p == NULL)
		printf("当前通讯录列表为空!!!\n");
	else
	{
	printf("请输入你要搜索联系人的姓名:\n");
	scanf("%s",name);
	while(p != NULL)
	{
		if(strcmp(p -> name,name) == 0)
		{
		printf("\
姓名         手机号                  归属地\n");
		printf("%-13s",p -> name);
		printf("%-24d",p -> tel);
		printf("%-30s\n",p -> loc);
		printf("------------------------------------------------------------\n");
		printf("请选择要修改联系人的选项:\n\
1、姓名\n\
2、电话\n\
3、归属地\n\
4、多项修改\n");
		scanf("%d",&n);
		getchar();
		if(n > 4 || n < 1)
		{
			printf("输入错误!!!\n");
			edit(head);
		}
		else
		{
			switch(n)
			{
    				case 1:
  					{
   						printf("请输入要修改为的姓名\n");
						scanf("%s",p -> name);
						printf("修改成功!!!");
						break;
					}
				case 2:
   					{
  						printf("请输入要修改为的电话号码\n");
						scanf("%d",&p -> tel);
						printf("修改成功!!!");
						break;
					}
				case 3:
   					{
  						printf("请输入要修改为的归属地\n");
						scanf("%s",p -> loc);
						printf("修改成功!!!");
						break;
					}
				case 4:
 					{
 						printf("请输入要修改联系人的姓名、电话和归属地:\n");
 						scanf("%s",p -> name);
						scanf("%d",&p -> tel);
						getchar();
						scanf("%s",p -> loc);
						printf("修改成功!!!\n");
						break;
					}
			}
		}
		j++;
		}
		p = p -> next;
	}
	if(j == 0)
		printf("没有搜索到此联系人!\n");
	}

}

void del(Link head)
{
	int j = 0;
	char name[20];
	Link q = head;
	Link p = head -> next;
	if(p == NULL)
		printf("当前通讯录列表为空!\n");
	else
	{
		printf("请输入要删除联系人的姓名:\n");
		scanf("%s",name);
		while(p != NULL)
		{
			if(strcmp(p -> name,name) == 0)
			{
 				q -> next = p -> next;
				free(p);
				printf("删除成功!!\n");
				j++;
			}
			q = p;
			p = p -> next;
		}
		if(j == 0)
			printf("没有搜索到此联系人!\n");
	}
}

void display(Link head)
{
	Link p = head -> next;
		printf("\
姓名         手机号                  归属地\n");
	while(p != NULL)
	{
   		 printf("%-13s",p -> name);
		 printf("%-24d",p -> tel);
		 printf("%-30s\n",p -> loc);
		 p = p -> next;
	}
}

void regular_name(Link head)
{
	char name[10];
	int q = 1;
	Link p = head -> next;
	if(p == NULL)
		printf("当前通讯录列表为空!!!\n");
	else
	{
		while(q == 1)
		{
			q = 0;
			for(p = head -> next;p -> next != NULL;p = p -> next)
			{
 				if(strcmp(p -> name,p -> next -> name) > 0)
				{
 					strcpy(name,p -> next -> name);
					strcpy(p -> next -> name,p -> name);
					strcpy(p -> name,name);
					q = 1;
				} 
			}
		}
		display(head);
	}
}

void regular(Link head)
{
	int n;
	Link p = head -> next;
	printf("请选择排序方式:\n\
1、序号排序\n\
2、姓名排序\n");
	scanf("%d",&n);
	if(n < 1 || n > 2)
	{
		printf("输入错误!!!\n");
		regular(head);
	}
	else
	{
		switch(n)
		{
			case 1:display1(head);break;
			case 2:regular_name(head);break;
		}
	}
}

void del_same(Link head)
{
	Link p,t;
	Link q = head -> next;
	Link k = head -> next;
	if(q == NULL)
		printf("当前通讯录列表为空!!!\n");
	else
	{
		while(k -> next != NULL)
		{
			for(p = k -> next;p != NULL;)
			{
				if(strcmp(k -> name,p -> name) == 0)
				{
					q -> next = p -> next;
					t = p -> next;
					free(p);
					p = t;
				}
				else
				{
					q = p;
					p = p -> next;
				}
			}
			k = k -> next;
		}
		printf("删除成功!!!\n");
		printf("------------------------------------------------------------------\n");
		display(head);
	}
}

int save(Link head)
{
	FILE * fp;
	Link p = head -> next;
	char c[3],s[20];

	printf("是否要保存联系人?(yes保存no退出)\n");
	scanf("%s",c);
	if(strcmp(c,"yes") == 0)
	{
		if(p == NULL)
		{
			printf("当前通讯录中没有联系人!谢谢使用!\n");
			exit(0);
		}
		else
		{
			printf("请输入要保存到本地的文件名:\n");
			scanf("%s",s);
			fp = fopen(s,"w+");
			while(p != NULL)
			{
				fwrite(p,sizeof(po),1,fp);
				
				p = p -> next;
			}
			fclose(fp);
			printf("保存成功!\n");
			exit(0);
		}

	}
	else if(strcmp(c,"no") == 0)
	{
		printf("谢谢使用!\n");
		exit(0);
	}
	else
	{
		printf("输入错误!请重新输入!\n");
		save(head);
	}

}

Link open()
{
	FILE * fp;
	char c[20], ch;
	Link head = (Link)malloc(sizeof(Node));

	Link p1 = head;
	Link p2 = NULL;

	printf("请输入要打开文件的名称:\n");
	scanf("%s",c);
	fp = fopen(c,"r");
	fseek(fp,0,SEEK_SET);
	if(fp == NULL)
	{
		printf("打开失败!\n");
		exit(-1);
	}
	else
	{
		ch = fgetc(fp);
		if(ch == EOF)
		{
			printf("通讯录为空!\n");
			exit(-1);
		}
		else
		{
			fseek(fp,0,SEEK_SET);
			while(1)
			{
  				p2 =(Link)malloc(sizeof(Node));
				if(p2 == NULL)
				{
  					printf("open malloc error!\n");
					exit(-1);
				}
			    p1 -> next = p2;
				fread(p2,sizeof(po),1,fp);
				if(feof(fp) == 1)
					break;
				p1 = p2;
			}
			p1 -> next = NULL;
			fclose(fp);
			printf("读取文件成功!\n");
			return head;
		}

	}


}

int operate(Link head,int n)
{
	switch(n)
	{
		case 1:add(head);break;
		case 2:edit(head);break;
		case 3:display1(head);break;
		case 4:search(head);break;
		case 5:len(head);break;
		case 6:del(head);break;
		case 7:regular(head);break;
		case 8:clear(head);break;
		case 9:del_same(head);break;
		case 0:save(head);break;
		case 10:break;
		default:{printf("请重新输入有效数字!\n");break;}
	}
}

int main()
{
	int n;
	Link head = NULL;
	Link new_node = NULL;

    create_head(&head);

	while(1)
	{
		n = show();
		if(n == 10)
			head = open();
		operate(head,n);
	}
}

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值