简易通讯录c语言链表,基于链表的通讯录简单程序

ca56232b3bbedf9a539d07f37fffb99a.gif

3144d8b7615c79d9f638db40d5689d26.gif

a218af6549b45ee526caf607ebff1358.gif

0f8df0e29816ae721419de940fb833d1.gif

基于链表的通讯录简单程序

#include

#include

#include

struct address{                         /*定义结构*/

char name[30];

char street[40];

char city[20];

char state[3];

char zip[11];

struct address *next;                  /*后继指针*/

struct address *prior;                 /*前导指针*/

};

struct address *start;                 /*首结点*/

struct address *last;                  /*尾结点*/

struct address *find(char *);          /*声明查找函数*/

void enter(void),search(void),save(void);                    /*函数声明*/

void load(void),list(void);

void mldelete(struct address **,struct address **);

void dls_store(struct address *i,struct address **start,

struct address **last);

void inputs(char *,char *,int),display(struct address *);

int menu_select(void);

int main(void)

{

start = last = NULL;

for(;;)

{switch(menu_select())

{case 1:enter();

continue;

case 2:mldelete(&start,&last);

continue;

case 3:list();

continue;

case 4:search();

continue;

case 5:save();

continue;

case 6:load();

continue;

case 7:exit(0);

}

}

}

int menu_select(void)                /*主目录*/

{

char s[80];

int c;

printf("1.Enter a name \n");

printf("2.Delete a name \n");

printf("3.List the file \n");

printf("4.Search \n");

printf("5.Save the file \n");

printf("6.Load the file \n");

printf("7.Quit \n");

do{

printf("\nEnter your choice:");

gets(s);

c = atoi(s);

}while(c<0||c>7);                 /*超出选项范围时,提示重新输入*/

return c;                          /*返回输入值*/

}

void enter(void)                           /*输入函数,本函数循环输入资料,当输入姓名为空时退出*/

{struct address *info;                     /*定义当前结点*/

for(;;){

info=(struct address *)malloc(sizeof(struct address));   /*为当前结点分配空间*/

if(!info)

{printf("\n Out of memory");

exit(0);                                               /*如果分配空间失败,退出程序*/

}

inputs("Enter name:",info->name,30);

if(!info->name[0])break;                                /*如果输入姓名为空,结束循环*/

inputs("Enter street:",info->street,40);

inputs("Enter city:",info->city,20);

inputs("Enter state:",info->state,3);

inputs("Enter zip:",info->zip,10);

dls_store(info,&start,&last);           /*调用结点插入函数*/

}

}

void inputs(char *prompt,char *s,int count)         /*输入函数,有越界检测功能*/

{

char p[255];

do{

printf(prompt);

fgets(p,254,stdin);

if(strlen(p)>count)printf("\nToo Long\n");

}while(strlen(p)>count);

p[strlen(p)-1]=0;

strcpy(s,p);

}

void dls_store(                    /*数据插入函数,也是本例的关键函数*/

struct address *i,          /*接受传入的当前输入结点地址*/

struct address **start,     /*接受传入的首结点地址*/

struct address **last       /*接受传入的尾结点地址*/

)

{

struct address *old,*p;              /*定义临时指针*/

if(*last==NULL)                      /*如果尾结点为空,意味着当前链表为空*/

{i->next=NULL;                      /*当前结点的后驱赋空*/

i->prior=NULL;                     /*当前结点的前驱赋空*/

*last=i;                           /*尾结点定义为当前结点*/

*start=i;                          /*首结点定义为当前结点*/

return;                            /*返回调用函数*/

}

/*如果链表不为空*/

p=*start;                            /*p取入口地址(也就是首结点地址)*/

old=NULL;                            /*old赋空*/

while(p){                            /*如果p不为空时,执行特循环体,查找比当前结点应该插入的位置*/

if(strcmp(p->name,i->name)<0)       /*如果当前结点的name域比p(首结点)大时(实现以name域升序排序)*/

{old=p;                            /*old暂存p地址*/

p=p->next;                        /*p取下一结点*/

}

else                                /*如果当前输入数据中的name域比p小时,把数据插入结点p之前*/

{if(p->prior)                      /*如果p的前驱不为空时*/

{p->prior->next=i;                /*令p的前驱的next域指向当前结点*/

i->next=p;                       /*令当前结点的后继指向p*/

i->prior=p->prior;               /*令当前结点的前驱指向p的前驱*/

p->prior=i;                      /*令p的前驱为当前结点*/

return;                          /*插入完成,返回调用函数*/

}

i->next=p;                        /*如果p的前驱为空时,把当前结点作为首结点,并令当前结点的后驱为p*/

i->prior=NULL;                    /*定义当前结点的前驱为空*/

p->prior=i;                       /*p的前驱为当前结点*/

*start=i;                         /*首结点(入口)为当前结点*/

return;                           /*插入完成,返回调用函数*/

}

}                                   /*循环体结束*/

old->next=i;                        /*如果在整个链表都找不到name域比当前数据的name域大的结点,

*把当前数据放在作为尾结点放在最后*/

i->next=NULL;                       /*令链表尾结点后驱批向当前结点,当前结点的后驱为空*/

i->prior=old;                       /*令当前结点的前驱为之前的最后结点*/

*last=i;                            /*尾结点取i地址*/

}

void mldelete(struct address **start,struct address **last)        /*删除函数*/

{

struct address *info;

char s[80];

inputs("Enter name:",s,30);             /*输入欲删除结点的name域内容*/

info=find(s);                           /*查找该内容*/

if(info)                                /*如果找到*/

{if(*start==info)                      /*如果该结点为首结点,把该结点的下驱作为新的首结点(入口)*/

{*start=info->next;

if(*start)(*start)->prior=NULL;      /*如果新入口不为空,把入口的前驱置空*/

else *last=NULL;                     /*如果新入口为空,把尾结点置空,链表为空*/

}

else                                  /*如果欲删除的结点不是首结点*/

{info->prior->next=info->next;       /*令该结点的前驱的next指针指向该结点的后驱,

*又令该结点的后驱的prior指点指向该结点的前驱*/

if(info!=*last)                     /*如果该结点是尾结点,则令该结点的前驱为尾结点*/

info->next->prior=info->prior;

else

*last=info->prior;

}

free(info);                           /*释放该结点所占用的内存*/

}

}

struct address *find(char *name)         /*查找函数,形参为欲查找结点的name域*/

{

struct address *info;

info=start;

while(info)

{

if(!strcmp(name,info->name))return info;

info=info->next;

}

printf("Name not found.\n");

return NULL;

}

/*输出整个链表*/

void list(void)

{

struct address *info;

info=start;

while(info)

{display(info);

info=info->next;

}

printf("\n\n");

}

void display(struct address *info)         /*输出传入结点函数*/

{

printf("%s\n",info->name);

printf("%s\n",info->street);

printf("%s\n",info->city);

printf("%s\n",info->state);

printf("%s\n",info->zip);

printf("\n\n");

}

void search(void)                             /*查找函数*/

{

char name[40];

struct address *info;

printf("Enter name to find:");             /*输入欲查找的姓名*/

gets(name);

info=find(name);

if(!info)printf("Not found\n");            /*如果没找到,显示Not found*/

else display(info);                        /*如果找到,显示该结点资料*/

}

void save(void)                             /*保存函数*/

{

struct address *info;

FILE *fp;

fp=fopen("mlist","wb");                   /*生成文件*/

if(!fp)

{printf("Cannot open file.\n");exit(1);}

printf("\nSaveing File\n");

info=start;

while(info)                                 /*把链表写入文件*/

{fwrite(info,sizeof(struct address),1,fp);

info=info->next;

}

fclose(fp);                                 /*链表全部写入文件后,关闭文件*/

}

void load()                               /*调用预存文件函数*/

{struct address *info;

FILE *fp;                                /*打开文件*/

fp=fopen("mlist","rb");

if(!fp){

printf("Cannot open file.\n");

exit(1);

}

while(start){                           /*释放当前内存链表*/

info=start->next;

free(start);

start=info;

}

start=last=NULL;                         /*链表为空*/

printf("\nLoading file\n");              /*调用文件*/

while(!feof(fp))                         /*如果文件未到结尾,循环读取文件*/

{info=(struct address *)malloc(sizeof(struct address));   /*为结点分配内存*/

if(!info)

{printf("out of Memory");

return;

}

if(1!=fread(info,sizeof(struct address),1,fp))break;     /*如果读取失败,退出*/

dls_store(info,&start,&last);                            /*如果读取成败,调用插入函数,把数据插入链表*/

}                                                         /*文件到结尾,循环结束*/

fclose(fp);                                                /*关闭文件,释放内存*/

}

搜索更多相关主题的帖子:

链表 通讯录

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值