#include <stdio.h>
#include <malloc.h>
#include <string.h>
#include <stdlib.h>
#define MAXSIZE 20
/*定义结构体,保存通讯录中每个联系人的信息,person为节点类型,linkman为指向
{
char name[MAXSIZE];
char phone[MAXSIZE];
struct node *next; /*存放后继元素地址*/
}person,*linkman;
/*定义一个枚举*/
enum sel
{
EXIT,
CREATE,
ADD,
DELETE,
SEARCH,
MODIFY,
SHOW,
SAVE,
CLEAR
linkman Init_person()
{
linkman Head; /*定义一个头节点*/
Head = (linkman)malloc(sizeof(person));
if(Head)
{
Head->next = NULL;
}
printf("通讯录创建成功!\n请添加联系人!\n");
return Head;
int length_person(linkman Head)
{
linkman p = Head; /*p指向头节点*/
int count = -1; /*用于计算链表的长度*/
while(p)
{
p = p->next; /*遍历链表*/
count++;
}
return count; /*返回链表的长度*/
linkman locate_person_pos(linkman Head,int i)
{
linkman p;
int j;
p = Head; /*p指向头节点*/
j = 0;
while(p && j < i) /*查找第i个节点*/
{
p = p->next;
j++;
}
if((j != i) || !p)
{
return NULL;
} /*第i个节点不存在*/
return p; /*返回第i个节点*/
int locate_person(linkman Head,char *dname)
{
int count = 0; /*用于计数*/
linkman p = Head; /*p指向头节点*/
while(p)
{
if(strcmp(p->name,dname) == 0)
{
break;
}
else
{
p = p->next;
count++;
}
}
return count; /*返回指定联系人所在位置*/
}
/*添加联系人*/
linkman p;
linkman q;
p = locate_person_pos(Head,i-1); /*p指向第i-1个节点*/
if(!p)
{
printf("i error!\n");
return 0;
}
q = (linkman)malloc(sizeof(person));
if(!q)
{
printf("fail to apply for space!");
return 0;
}
strcpy(q->name,name); /*给节点赋值*/
strcpy(q->phone,phone);
q->next = p->next;
p->next = q;
return 1;
}
/*将联系人按照姓名进行排序*/
linkman sort_person(linkman Head)
{
linkman p;
linkman q;
char temp[MAXSIZE]; /*定义两个中间字符数组*/
char temp2[MAXSIZE];
for(p = Head;p->next != NULL;p = p->next)
{
for(q = Head; q->next != NULL; q= q->next)
{
if(strcmp(q->name,q->next->name)>0) /*比较大小,交换节点信息*/
{
strcpy(temp,q->name);
strcpy(q->name,q->next->name);
strcpy(q->next->name,temp);
strcpy(temp2,q->phone);
strcpy(q->phone,q->next->phone);
strcpy(q->next->phone,temp2);
/*将数组清空*/
memset(temp,0,MAXSIZE);
memset(temp2,0,MAXSIZE);
}
}
}
return Head; /*返回头节点*/
}
/*遍历链表统计同名联系人的个数*/
int search(linkman Head,char *dname)
{
linkman p;
int count = 0; /*用于计数*/
p = Head; /*p指向头节点*/
while(p != NULL)
{
if(strcmp(dname,p->name) == 0)
{
count++;
}
p = p->next;
}
return count;
}
/*查找指点联系人的信息*/
int search_person(linkman Head,char *sname)
{
linkman p;
int count = 0;
while(p != NULL)
{
if(strcmp(sname,p->name) == 0)
{
/*打印指定联系人的信息*/
printf("name:%s\tphone:%s\t\n",p->name,p->phone);
count++;
}
p = p->next;
}
if(count == 0)
{
printf("该联系人不存在!\n");
}
return 1;
}
/*删除指定联系人*/
int delete_person(linkman Head,char *dname)
{
int count;
int location; /*接指定联系人的位置*/
int i;
linkman p;
linkman q;
if(Head == NULL || Head->next == NULL)
{
printf("该通讯录不存在!\n");
return 0;
}
count = search(Head,dname);
/*判断是否有同名的联系人,如果有,择删除指定的同名联系人*/
if(count >= 2)
{
search_person(Head,dname);
printf("请选择要删除第几个人:\n");
scanf("%d",&i);
getchar();
while(i > count || i < 1)
{
printf("输入错误,请重新选择!\n");
scanf("%d",&i);
getchar();
}
location = locate_person(Head,dname);
p = locate_person_pos(Head,location + (i - 1) -1);
}
/*若无同名联系人,则删除该联系人*/
else
{
location = locate_person(Head,dname);
/*找到指定联系人的位置*/
/*p指向指定联系人的上一个节点位置*/
p = locate_person_pos(Head,location-1);
}
if(p == NULL || p->next == NULL)
{
printf("该联系人不存在!\n");
return 0;
}
q = p->next;
p->next = q->next;
free(q); /*释放指定联系人的节点*/
printf("删除联系人成功!\n");
return 1;
}
/*修改联系人信息*/
int modify_person(linkman Head,char *mname)
{
int count;
int location; /*接指定联系人的位置*/
int i;
char nphone[MAXSIZE];
char nname[MAXSIZE];
linkman p;
if(Head == NULL || Head->next == NULL)
{
printf("该通讯录不存在!\n");
return 0;
}
count = search(Head,mname);
/*判断是否有同名的联系人,如果有,择修改指定的同名联系人*/
if(count >= 2)
{
search_person(Head,mname);
printf("请选择要修改第几个人的信息:\n");
scanf("%d",&i);
getchar();
while(i > count || i < 1)
{
printf("输入错误,请重新选择!\n");
scanf("%d",&i);
getchar();
}
location = locate_person(Head,mname);
p = locate_person_pos(Head,location + (i -1));
}
/*若无同名联系人,则修改该联系人信息*/
else
{
location = locate_person(Head,mname);
/*找到指定联系人的位置*/
/*p指向指定联系人的节点位置*/
p = locate_person_pos(Head,location);
}
if(p == NULL)
{
printf("该联系人不存在!\n");
return 0;
}
printf("请输入修改联系人的新姓名:\n");
scanf("%s",nname);
printf("请输入修改联系人的新号码:\n");
scanf("%s",nphone);
strcpy(p->name,nname);
strcpy(p->phone,nphone);
printf("修改联系人成功!\n");
return 1;
}
/*释放所有节点*/
void free_person(linkman *Head)
{
linkman p;
linkman q;
p = *Head;
while(p) /*释放链表的所有节点*/
{
q = p;
p = p->next;
free(q);
}
*Head = NULL;
void clear_person(linkman *Head)
{
FILE *fp;
linkman p;
linkman q;
p = (*Head)->next; /*保留头节点*/
/*清空保存在文件中的联系人信息*/
fp = fopen("telephone.txt","w");
if(NULL == fp)
{
printf("open file fail!\n");
exit(1);
}
fclose(fp);
/*释放除头节点外的所有节点*/
while(p)
{
q = p;
p = p->next;
free(q);
}
(*Head)->next = NULL;
printf("清除所有联系人成功!\n");
}
/*打印所有联系人的信息*/
void show_person(linkman Head)
{
linkman p = Head->next; /*p指向头节点的下一个节点*/
if(NULL == Head->next)
{
printf("暂无联系人,请添加联系人!\n");
}
/*遍历打印节点信息*/
while(p)
{
printf("name:%s\tphone:%s\t\n",p->name,p->phone);
p = p->next;
}
printf("\n");
void save_person(linkman Head)
{
FILE * fp;
linkman p;
fp = fopen("telephone.txt","w"); /*打开文件*/
if(NULL == fp)
{
printf("open file fail!\n");
exit(1);
}
p = Head; /*p指向头节点*/
while(p != NULL) /*遍历所有节点*/
{
fwrite(p,sizeof(person),1,fp);/*将一个节点大小的内容写入文件中*/
p = p->next;
}
fclose(fp); /*关闭文件*/
printf("保存成功!\n");
}
/*从指定文件中读取联系人信息*/
linkman read_person()
{
linkman t2;
int read;
fp = fopen("telephone.txt","a+"); /*打开文件*/
if(NULL == fp)
{
printf("open file fail!\n");
exit(1);
}
fseek(fp,0,SEEK_SET);
ch = fgetc(fp); /*判断该文件是否为空*/
if(EOF == ch)
{
printf("该通讯录不存在!\n请先创建通讯录!\n");
return Head;
}
else
{
fseek(fp,0,SEEK_SET);
}
t1 = (linkman)malloc(sizeof(person));
Head = t1;
while(!feof(fp))
{
/*将文件中的一个节点大小的信息写入链表的节点中*/
read = fread(t1,sizeof(person),1,fp);
if(read != 1)
{
break;
}
t1->next = (linkman)malloc(sizeof(person));
t2 = t1;
t1 = t1->next;
}
t2->next=NULL;
free(t1); /*将多余的一个节点释放*/
fclose(fp); /*关闭文件*/
printf("读取通讯录成功!\n");
return Head; /*返回头节点*/
}
/*菜单目录*/
void menu()
{
printf("****************************\n");
printf(" 欢迎使用通讯录\n");
printf("1. 创建通讯录\n");
printf("2. 添加联系人\n");
printf("3. 删除指定联系人\n");
printf("4. 查找指定联系人\n");
printf("5. 修改指定联系人信息\n");
printf("6. 显示所有联系人\n");
printf("7. 保存所有联系人\n");
printf("8. 清空所有联系人\n");
printf("0. 退出通讯录\n");
printf("***************************\n");
}
int main()
{
linkman Head; /*定义头节点*/
int sel;
char name[MAXSIZE];
char phone[MAXSIZE];
char dname[MAXSIZE];
char sname[MAXSIZE];
char mname[MAXSIZE];
Head = read_person(); /*读取文件中的联系人信息*/
while(1)
{
menu();
printf("请选择:\n");
scanf("%d",&sel);
getchar();
switch(sel)
{
case CREATE:
{
Head = Init_person();
break;
}
case ADD:
{
printf("请输入姓名:\n");
scanf("%s",name);
printf("请输入电话号码:\n");
scanf("%s",phone);
insert_person(Head,length_person(Head)+1,name,phone);
sort_person(Head);
break;
}
case DELETE:
{
printf("请输入要删除的联系人姓名:\n");
scanf("%s",dname);
delete_person(Head,dname);
break;
}
case SEARCH:
{
printf("请输入姓名:\n");
scanf("%s",sname);
search_person(Head,sname);
break;
}
case MODIFY:
{
printf("请输入要修改的联系人姓名:\n");
scanf("%s",mname);
modify_person(Head,mname);
sort_person(Head);
break;
}
case SHOW:
{
show_person(Head);
break;
}
case SAVE:
{
save_person(Head);
break;
}
case CLEAR:
{
clear_person(&Head);
break;
}
case EXIT:
{
free_person(&Head);
return 0;
break;
}
default:
{
printf("输入错误!\n请重新输入!\n");
break;
}
}
}
return 0;
}
#include <malloc.h>
#include <string.h>
#include <stdlib.h>
#define MAXSIZE 20
/*定义结构体,保存通讯录中每个联系人的信息,person为节点类型,linkman为指向
person类型节点的指针类型*/
typedef struct node{
char name[MAXSIZE];
char phone[MAXSIZE];
struct node *next; /*存放后继元素地址*/
}person,*linkman;
/*定义一个枚举*/
enum sel
{
EXIT,
CREATE,
ADD,
DELETE,
SEARCH,
MODIFY,
SHOW,
SAVE,
CLEAR
};
linkman Init_person()
{
linkman Head; /*定义一个头节点*/
Head = (linkman)malloc(sizeof(person));
if(Head)
{
Head->next = NULL;
}
printf("通讯录创建成功!\n请添加联系人!\n");
return Head;
}
int length_person(linkman Head)
{
linkman p = Head; /*p指向头节点*/
int count = -1; /*用于计算链表的长度*/
while(p)
{
p = p->next; /*遍历链表*/
count++;
}
return count; /*返回链表的长度*/
}
linkman locate_person_pos(linkman Head,int i)
{
linkman p;
int j;
p = Head; /*p指向头节点*/
j = 0;
while(p && j < i) /*查找第i个节点*/
{
p = p->next;
j++;
}
if((j != i) || !p)
{
return NULL;
} /*第i个节点不存在*/
return p; /*返回第i个节点*/
}
int locate_person(linkman Head,char *dname)
{
int count = 0; /*用于计数*/
linkman p = Head; /*p指向头节点*/
while(p)
{
if(strcmp(p->name,dname) == 0)
{
break;
}
else
{
p = p->next;
count++;
}
}
return count; /*返回指定联系人所在位置*/
}
/*添加联系人*/
int insert_person(linkman Head,int i,char *name,char *phone)
{linkman p;
linkman q;
p = locate_person_pos(Head,i-1); /*p指向第i-1个节点*/
if(!p)
{
printf("i error!\n");
return 0;
}
q = (linkman)malloc(sizeof(person));
if(!q)
{
printf("fail to apply for space!");
return 0;
}
strcpy(q->name,name); /*给节点赋值*/
strcpy(q->phone,phone);
q->next = p->next;
p->next = q;
return 1;
}
/*将联系人按照姓名进行排序*/
linkman sort_person(linkman Head)
{
linkman p;
linkman q;
char temp[MAXSIZE]; /*定义两个中间字符数组*/
char temp2[MAXSIZE];
for(p = Head;p->next != NULL;p = p->next)
{
for(q = Head; q->next != NULL; q= q->next)
{
if(strcmp(q->name,q->next->name)>0) /*比较大小,交换节点信息*/
{
strcpy(temp,q->name);
strcpy(q->name,q->next->name);
strcpy(q->next->name,temp);
strcpy(temp2,q->phone);
strcpy(q->phone,q->next->phone);
strcpy(q->next->phone,temp2);
/*将数组清空*/
memset(temp,0,MAXSIZE);
memset(temp2,0,MAXSIZE);
}
}
}
return Head; /*返回头节点*/
}
/*遍历链表统计同名联系人的个数*/
int search(linkman Head,char *dname)
{
linkman p;
int count = 0; /*用于计数*/
p = Head; /*p指向头节点*/
while(p != NULL)
{
if(strcmp(dname,p->name) == 0)
{
count++;
}
p = p->next;
}
return count;
}
/*查找指点联系人的信息*/
int search_person(linkman Head,char *sname)
{
linkman p;
int count = 0;
p = Head; /*p指向头节点*/
while(p != NULL)
{
if(strcmp(sname,p->name) == 0)
{
/*打印指定联系人的信息*/
printf("name:%s\tphone:%s\t\n",p->name,p->phone);
count++;
}
p = p->next;
}
if(count == 0)
{
printf("该联系人不存在!\n");
}
return 1;
}
/*删除指定联系人*/
int delete_person(linkman Head,char *dname)
{
int count;
int location; /*接指定联系人的位置*/
int i;
linkman p;
linkman q;
if(Head == NULL || Head->next == NULL)
{
printf("该通讯录不存在!\n");
return 0;
}
count = search(Head,dname);
/*判断是否有同名的联系人,如果有,择删除指定的同名联系人*/
if(count >= 2)
{
search_person(Head,dname);
printf("请选择要删除第几个人:\n");
scanf("%d",&i);
getchar();
while(i > count || i < 1)
{
printf("输入错误,请重新选择!\n");
scanf("%d",&i);
getchar();
}
location = locate_person(Head,dname);
p = locate_person_pos(Head,location + (i - 1) -1);
}
/*若无同名联系人,则删除该联系人*/
else
{
location = locate_person(Head,dname);
/*找到指定联系人的位置*/
/*p指向指定联系人的上一个节点位置*/
p = locate_person_pos(Head,location-1);
}
if(p == NULL || p->next == NULL)
{
printf("该联系人不存在!\n");
return 0;
}
q = p->next;
p->next = q->next;
free(q); /*释放指定联系人的节点*/
printf("删除联系人成功!\n");
return 1;
}
/*修改联系人信息*/
int modify_person(linkman Head,char *mname)
{
int count;
int location; /*接指定联系人的位置*/
int i;
char nphone[MAXSIZE];
char nname[MAXSIZE];
linkman p;
if(Head == NULL || Head->next == NULL)
{
printf("该通讯录不存在!\n");
return 0;
}
count = search(Head,mname);
/*判断是否有同名的联系人,如果有,择修改指定的同名联系人*/
if(count >= 2)
{
search_person(Head,mname);
printf("请选择要修改第几个人的信息:\n");
scanf("%d",&i);
getchar();
while(i > count || i < 1)
{
printf("输入错误,请重新选择!\n");
scanf("%d",&i);
getchar();
}
location = locate_person(Head,mname);
p = locate_person_pos(Head,location + (i -1));
}
/*若无同名联系人,则修改该联系人信息*/
else
{
location = locate_person(Head,mname);
/*找到指定联系人的位置*/
/*p指向指定联系人的节点位置*/
p = locate_person_pos(Head,location);
}
if(p == NULL)
{
printf("该联系人不存在!\n");
return 0;
}
printf("请输入修改联系人的新姓名:\n");
scanf("%s",nname);
printf("请输入修改联系人的新号码:\n");
scanf("%s",nphone);
strcpy(p->name,nname);
strcpy(p->phone,nphone);
printf("修改联系人成功!\n");
return 1;
}
/*释放所有节点*/
void free_person(linkman *Head)
{
linkman p;
linkman q;
p = *Head;
while(p) /*释放链表的所有节点*/
{
q = p;
p = p->next;
free(q);
}
*Head = NULL;
}
void clear_person(linkman *Head)
{
FILE *fp;
linkman p;
linkman q;
p = (*Head)->next; /*保留头节点*/
/*清空保存在文件中的联系人信息*/
fp = fopen("telephone.txt","w");
if(NULL == fp)
{
printf("open file fail!\n");
exit(1);
}
fclose(fp);
/*释放除头节点外的所有节点*/
while(p)
{
q = p;
p = p->next;
free(q);
}
(*Head)->next = NULL;
printf("清除所有联系人成功!\n");
}
/*打印所有联系人的信息*/
void show_person(linkman Head)
{
linkman p = Head->next; /*p指向头节点的下一个节点*/
if(NULL == Head->next)
{
printf("暂无联系人,请添加联系人!\n");
}
/*遍历打印节点信息*/
while(p)
{
printf("name:%s\tphone:%s\t\n",p->name,p->phone);
p = p->next;
}
printf("\n");
}
void save_person(linkman Head)
{
FILE * fp;
linkman p;
fp = fopen("telephone.txt","w"); /*打开文件*/
if(NULL == fp)
{
printf("open file fail!\n");
exit(1);
}
p = Head; /*p指向头节点*/
while(p != NULL) /*遍历所有节点*/
{
fwrite(p,sizeof(person),1,fp);/*将一个节点大小的内容写入文件中*/
p = p->next;
}
fclose(fp); /*关闭文件*/
printf("保存成功!\n");
}
/*从指定文件中读取联系人信息*/
linkman read_person()
{
FILE *fp;
linkman t2;
linkman Head; /*定义一个头节点*/
int read;
fp = fopen("telephone.txt","a+"); /*打开文件*/
if(NULL == fp)
{
printf("open file fail!\n");
exit(1);
}
fseek(fp,0,SEEK_SET);
ch = fgetc(fp); /*判断该文件是否为空*/
if(EOF == ch)
{
printf("该通讯录不存在!\n请先创建通讯录!\n");
return Head;
}
else
{
fseek(fp,0,SEEK_SET);
}
t1 = (linkman)malloc(sizeof(person));
Head = t1;
while(!feof(fp))
{
/*将文件中的一个节点大小的信息写入链表的节点中*/
read = fread(t1,sizeof(person),1,fp);
if(read != 1)
{
break;
}
t1->next = (linkman)malloc(sizeof(person));
t2 = t1;
t1 = t1->next;
}
t2->next=NULL;
free(t1); /*将多余的一个节点释放*/
fclose(fp); /*关闭文件*/
printf("读取通讯录成功!\n");
return Head; /*返回头节点*/
}
/*菜单目录*/
void menu()
{
printf("****************************\n");
printf(" 欢迎使用通讯录\n");
printf("1. 创建通讯录\n");
printf("2. 添加联系人\n");
printf("3. 删除指定联系人\n");
printf("4. 查找指定联系人\n");
printf("5. 修改指定联系人信息\n");
printf("6. 显示所有联系人\n");
printf("7. 保存所有联系人\n");
printf("8. 清空所有联系人\n");
printf("0. 退出通讯录\n");
printf("***************************\n");
}
int main()
{
linkman Head; /*定义头节点*/
int sel;
char name[MAXSIZE];
char phone[MAXSIZE];
char dname[MAXSIZE];
char sname[MAXSIZE];
char mname[MAXSIZE];
Head = read_person(); /*读取文件中的联系人信息*/
while(1)
{
menu();
printf("请选择:\n");
scanf("%d",&sel);
getchar();
switch(sel)
{
case CREATE:
{
Head = Init_person();
break;
}
case ADD:
{
printf("请输入姓名:\n");
scanf("%s",name);
printf("请输入电话号码:\n");
scanf("%s",phone);
insert_person(Head,length_person(Head)+1,name,phone);
sort_person(Head);
break;
}
case DELETE:
{
printf("请输入要删除的联系人姓名:\n");
scanf("%s",dname);
delete_person(Head,dname);
break;
}
case SEARCH:
{
printf("请输入姓名:\n");
scanf("%s",sname);
search_person(Head,sname);
break;
}
case MODIFY:
{
printf("请输入要修改的联系人姓名:\n");
scanf("%s",mname);
modify_person(Head,mname);
sort_person(Head);
break;
}
case SHOW:
{
show_person(Head);
break;
}
case SAVE:
{
save_person(Head);
break;
}
case CLEAR:
{
clear_person(&Head);
break;
}
case EXIT:
{
free_person(&Head);
return 0;
break;
}
default:
{
printf("输入错误!\n请重新输入!\n");
break;
}
}
}
return 0;
}