本文介绍了我通讯录项目各个功能的编写过程以及大体思路。
1.头文件以及结构体的定义
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define OK 1
#define ERROR 0
typedef char Elemtype;
typedef char Status;
typedef struct Node
{
Elemtype name[10];
Elemtype tel[12];
struct Node *next;
}Node,*Address_list;
2.初始化过程
申请头结点,使用malloc函数为头结点分配空间,让头指针指向头结点,头结点的指针域指向NULL。
为什么要申请头结点?
为了保证处理第一个节点(非头结点)和后面节点时候设计的算法相同,实现程序的高效性。
/************初始化****************/
Status Initaddress(Address_list *aptr)
{
Node *p=(Node *)malloc(sizeof(Node));//申请头结点
if(p==NULL)
return ERROR;
p->next=NULL;
*aptr=p;
return OK;
}
2.插入新节点(实现新建联系人功能)
第一步:申请一个新结点用于记录新联系人的信息
使用malloc函数,需要强制转换。
第二步:将这个新结点插入到链表的最后
新申请一个tmp指针指向tmp头结点,用while语句是tmp指针后移,直到链表尾部,即tmp->next的值为NULL时,进行 如下操作:
将tmp指向新申请的结点,新节点的指针域指向NULL。
Status Insert(Address_list aptr,Elemtype e[],Elemtype f[])
{
Node *p=(Node *)malloc(sizeof(Node));
if(p==NULL)
{
printf("堆空间已满\n");
return ERROR;
}
strcpy(p->name,e);
strcpy(p->tel,f);
Address_list tmp=aptr;
while(tmp->next!=NULL)
{
tmp=tmp->next;
if(strcmp(e,tmp->name)==0)
{
printf("此联系人已存在!\n");
return ERROR;
}
}
p->next=NULL;
tmp->next=p;
return OK;
}
4.删除结点(删除联系人)
第一步:找到需要删除的结点
使用strcmp函数将需要删除联系人姓名与链表结点中数据依次对比,相同则执行第二步删除工作,不同与下一个结点对比,若是到链表结尾依然没有找到,则代表该联系人不存在。
第二步:删除该结点
Status Delete(Address_list aptr,Elemtype e[],Elemtype f[])
{
Address_list tmp=aptr;
while(1)
{
if(strcmp(e,tmp->next->name)==0)
break;
if(tmp->next->next==NULL&&strcmp(e,tmp->next->name)!=0)
{
printf("此联系人不存在!\n");
return ERROR;
}
tmp=tmp->next;
}
Node *tmp2=tmp->next;
strcpy(e,tmp2->name);
strcpy(f,tmp2->tel);
tmp->next=tmp2->next;
free(tmp2);
return OK;
}
5.查找联系人
查找与上文删除联系人的第一步相同,使用strcmp函数即可,然后将该结点信息打印,较为简单。
Status Find(Address_list aptr,Elemtype e[],Elemtype f[])
{
Address_list tmp=aptr;
while(1)
{
if(strcmp(e,tmp->next->name)==0)
break;
if(tmp->next->next==NULL&&strcmp(e,tmp->next->name)!=0)
{
printf("此联系人不存在!\n");
return ERROR;
}
tmp=tmp->next;
}
strcpy(f,tmp->next->tel);
return OK;
}
6.按联系人姓名修改号码
第一步:找到该结点,同上文查找
第二步:修改信息,用strcpy函数将修改后的号码赋值给该结点的Tel域
Status Modify(Address_list aptr,Elemtype e[],Elemtype f[])
{
Address_list tmp=aptr;
while(1)
{
if(strcmp(e,tmp->next->name)==0)
break;
if(tmp->next->next==NULL&&strcmp(e,tmp->next->name)!=0)
{
printf("此联系人不存在!\n");
return ERROR;
}
tmp=tmp->next;
}
strcpy(tmp->next->tel,f);
return OK;
}
7.打印函数
Status Printlist(Address_list aptr)
{
Address_list tmp=aptr;
if(NULL==tmp)
{
printf("此表为空!\n");
return ERROR;
}
else
{
while(tmp!=NULL)
{
printf("%-10s",tmp->name);
printf("%s",tmp->tel);
printf("\n");
tmp=tmp->next;
}
printf("\n");
return OK;
}
}
8.将联系人按首字母排序
第一步:申请一个指针数组用于依次指向链表的每一个结点
第二步:将指针数组的内容进行排序
第三步:打印指针数组的内容
Status Sort(Address_list aptr)
{
int m=0;
Address_list tmp=aptr;
Node *a[100];
tmp=tmp->next;
while(tmp!=NULL)
{
a[m]=tmp;
m++;
tmp=tmp->next;
}
int i;
for(i=0;i<m-1;i++)
{
int j;
for(j=0;j<=m-2-i;j++)
{
if(strcmp(a[j]->name,a[j+1]->name)>0)
{
Node *tmp;
tmp=a[j];
a[j]=a[j+1];
a[j+1]=tmp;
}
}
}
for(i=0;i<m;i++)
{
printf("%-10s",a[i]->name);
printf("%s",a[i]->tel);
printf("\n");
}
return OK;
}
9.将通讯录的联系人信息保存到另一个TXT文件中
第一步:创建新的TXT文件
第二步:将链表信息逐个写入TXT文件中,用fwrite函数
Status Fwrite(Address_list aptr)
{
FILE *file=fopen("test5.txt","w+");
if(NULL==file)
{
perror("fopen");
return ERROR;
}
Address_list tmp=aptr;
tmp=tmp->next;
while(tmp!=NULL)
{
int count1=fwrite(tmp,sizeof(Node),1,file);
if(EOF==count1)
{
perror("fwrite");
fclose(file);
return ERROR;
}
tmp=tmp->next;
}
return OK;
}
10.读取TXT文件中的联系人信息
第一步:打开存有联系人信息的TXT文件
第二步:逐个读取联系人信息,用fread函数
Status Fread(Address_list aptr)
{
Address_list tmp=aptr;
FILE *file=fopen("test5.txt","a+");
if(NULL==file)
{
perror("fopen");
return ERROR;
}
fseek(file,0,SEEK_SET);
Node *p=(Node *)malloc(sizeof(Node));
while(fread(p,sizeof(Node),1,file)!=0)
{
p->next=NULL;
tmp->next=p;
tmp=tmp->next;
p=(Node *)malloc(sizeof(Node));
}
free(p);
return OK;
}
11.主函数
在主函数中引用上面写好的各个函数,再用一个switch函数实现执行时的供能选择。
int main()
{
Address_list Ltop;
Initaddress(&Ltop);
//Insert(Ltop,"yu","13327829295");
Fread(Ltop);
Printlist(Ltop);
Elemtype name[10];
Elemtype tel[12];
while(1)
{
int i;
printf("\t\t\t1.查看通讯录\n");
printf("\t\t\t2.新建联系人\n");
printf("\t\t\t3.删除联系人\n");
printf("\t\t\t4.查找联系人\n");
printf("\t\t\t5.按联系人修改号码\n");
printf("\t\t\t6.按联系人姓名排序\n");
printf("\t\t\t0.终止程序\n");
scanf("%d",&i);
switch(i)
{
case 1:
Printlist(Ltop);
break;
case 2:
do
{
printf("请输入新建联系人的姓名\n");
scanf("%s",name);
printf("请输入新建联系人的手机号\n");
scanf("%s",tel);
}
while(!Insert(Ltop,name,tel));
Fwrite(Ltop);
break;
case 3:
do
{
printf("请输入删除联系人的姓名\n");
scanf("%s",name);
}
while(!Delete(Ltop,name,tel));
printf("删除的联系人为:%s 号码为%s\n",name,tel);
Fwrite(Ltop);
break;
case 4:
do
{
printf("请输入查找联系人的姓名\n");
scanf("%s",name);
}
while(!Find(Ltop,name,tel));
printf("%s的号码为:%s\n",name,tel);
break;
case 5:
do
{
printf("请输入要修改号码的联系人姓名\n");
scanf("%s",name);
}
while(!Modify(Ltop,name,tel));
printf("请输入修改后的号码:\n");
scanf("%s",tel);
Modify(Ltop,name,tel);
printf("修改后%s的号码为:%s\n",name,tel);
Fwrite(Ltop);
break;
case 6:
Sort(Ltop);
break;
case 0:
return 0;
default:
printf("输入选项有误\n");
break;
}
}
return 0;
}
通讯录项目至此结束。