通讯录(数据结构)



#include<stdio.h>
#include<stdlib.h>
#include<string.h>
/*定义双链表作为通讯信息的物理存储结构*/
struct TXL{
    char name[30];
    char street[100];
    char city[30];
    char state[30];
    char zip[20];
    struct TXL *next;                  /*后继指针*/
    struct TXL *prior;                 /*前驱指针*/
};


struct TXL *start;                 /*首结点*/
struct TXL *last;                  /*尾结点*/
struct TXL *find(char *);          /*声明查找函数*/


/*声明本程序的可调用函数*/
void enter();
void search();
void save();
void load();
void list();
void mldelete(struct TXL **,struct TXL **);
void dls_store(struct TXL *i,struct TXL **start,
                struct TXL **last);
void inputs(char *,char *,int);
void display(struct TXL *);
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("…………^_^欢迎使用通讯录系统…………\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("*****************************************\n");
    do{
      printf("\nPlease enter your choice:\n");
      gets(s);
      c = atoi(s);
}while(c<0||c>7);                 /*超出选项范围时,提示重新输入*/


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


/*输入函数,本函数循环输入资料,当输入姓名为空时退出*/
void enter()
{
struct TXL *info;               /*定义当前结点*/


    for(;;)
{
        info=(struct TXL *)malloc(sizeof(struct TXL));   /*为当前结点分配空间*/
        if(!info)
{
    printf("\n Out of memory");
            exit(0);                                               /*如果分配空间失败,退出程序*/
}
        printf("输入空姓名结束:\n");
        inputs("Enter name:",info->name,30);
        if(!info->name[0])
break;                                /*如果输入姓名为空,结束循环*/
        inputs("Enter street:",info->street,100);
        inputs("Enter city:",info->city,30);
        inputs("Enter state:",info->state,30);
        inputs("Enter zip:",info->zip,20);


       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 TXL *i,          /*接受传入的当前输入结点地址*/
           struct TXL **start,     /*接受传入的首结点地址*/
           struct TXL **last       /*接受传入的尾结点地址*/
          )
{
struct TXL *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 TXL **start,struct TXL **last)
{
struct TXL *info;
    char s[80];


    inputs("Enter name:",s,30);             /*输入欲删除结点的name域内容*/
    info=find(s);                           /*查找该内容*/
    if(info)                                /*如果找到*/
{
printf("Deleting......\n");
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);                    /*释放该结点所占用的内存*/
printf("-Ok,deleted successfully!\n");
}
}


/*查讯函数,形参为欲查找结点的name域,完成查询功能*/
struct TXL *find(char *name)
{
struct TXL *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 TXL *info;
    info=start;
if(info==NULL)
printf("NO information!");
    while(info)
{
display(info);
        info=info->next;
}
    printf("\n\n");
}


 /*输出传入结点函数,实现将相应的查询的信息输出*/
void display(struct TXL *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 TXL *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 TXL *info;
    FILE *fp;
    fp=fopen("mlist","wb");                   /*生成文件*/
    if(!fp)
    {
printf("Cannot open file.\n");
return;
}
    printf("\nSaveing ……\n");
info=start;
    while(info)                                 /*把链表写入文件*/
{
fwrite(info,sizeof(struct TXL),1,fp);
        info=info->next;
}
printf("-ok!\n");
    fclose(fp);/*链表全部写入文件后,关闭文件*/


}


/*调用预存文件函数,将存储的文件调用读取*/
void load()
{
register int t, size;
    struct TXL *info,*temp=0;
    char *p;
    FILE *fp;                                     /*打开文件*/
    if((fp=fopen("mlist","r"))==NULL)
{
printf("Cannot open file!\n");
        exit(0);
}
    printf("\n\nLoading...\n");                    /*调用文件*/
    size=sizeof(struct TXL);           /*为结点分配内存*/
start==malloc(size);
    if(!start)                                       /*如果读取失败,返回*/
{
printf("Out of memory!\n");
        exit(0);
}
    info=start;
    p=(char*)info;
    while((*p++=getc(fp))!=EOF)
{
for(t=0;t<size-1;++t)
            *p++=getc(fp);
        info->next==malloc(size);
        if(!info->next)
{
printf("Out of memory!\n");
            return;
}
        info->prior=temp;
        temp=info;
        info=info->next;
        p=(char*)info;
}
    temp->next=0;
    last=temp;
    start->prior=0;
    fclose(fp);                                   /*关闭文件,释放内存*/
    printf("-OK!\n");
}
  • 7
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值