链表通讯录(带文件保存)
#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);
}
}