main.cpp
/***********************************************************
*版权所有 (C)2016, Li Ling
* 文件名称: main.cpp
* 文件标识:无
* 内容摘要:该代码用于获取满足后缀要求的第一个文件
* 其它说明:无
* 当前版本: V1.0
* 作 者:李玲
* 完成日期: 2016 12 28 *
* 修改记录0:
* 修改日期: 无
* 版本号: V1.0
* 修改人:Li Ling
* 修改内容:创建
**********************************************************/
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include"ll.h"
int main(void)
{
start = last = NULL;
system("color 3e");
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);
}
}
return 0;
}
/*********************************************************
* 功能描述:主目录函数
* 输入参数: c 选项
* 输出参数:无
* 返回值: c 输入值
* 其它说明:消息字段之间用分号(;)分隔
************************************************************ */
int menu_select(void) /*主目录*/
{
char s[80];
int c;
printf("…………欢迎使用迷你通讯录系统……………\n");
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; /*返回输入值*/
}
/*********************************************************
* 功能描述:输入函数
* 输入参数:info->name,info->city,info->phone,info->state,info->zip
* 输出参数:无
* 返回值: 空
* 其它说明:消息字段之间用分号(;)分隔
*************************************************************/
void enter() /*输入函数,本函数循环输入资料,当输入姓名为空时退出*/
{
struct address *info; /*定义当前结点*/
for(;;)
{
info=(struct address *)malloc(sizeof(struct address)); /*为当前结点分配空间*/
if(!info)
{
printf("\n Error");
exit(0); /*如果分配空间失败,退出程序*/
}
printf("输入空姓名结束:\n");
inputs("Enter name:",info->name,30);
if(!info->name[0])
break; /*如果输入姓名为空,结束循环*/
inputs("Enter phone:",info->phone,100);
inputs("Enter city:",info->city,30);
inputs("Enter state:",info->state,30);
inputs("Enter zip:",info->zip,11);
dls_store(info,&start,&last); /*调用结点插入函数*/
}
}
/*********************************************************
* 功能描述:输入函数
* 输入参数: p[255]
* 输出参数:无
* 返回值: 无
* 其它说明:消息字段之间用分号(;)分隔
************************************************************ */
void inputs(char *prompt,char *s,int count) /*输入函数,有越界检测功能*/
{
char p[255];
do
{
printf(prompt);
fgets(p,254,stdin);
if(strlen(p)>count) //strlen为开始扫描,直到碰到第一个字符串结束符'\0'为止
printf("\nToo Long\n");
}
while(strlen(p)>count);
p[strlen(p)-1]=0;
strcpy(s,p);
}
/*********************************************************
* 功能描述:数据插入函数
* 输入参数:struct address *i,struct address **start, struct address **last
* 输出参数:无
* 返回值: 无
* 其它说明:消息字段之间用分号(;)分隔
************************************************************ */
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;
i->next=p;
i->prior=p->prior;
p->prior=i;
return;
}
i->next=p; /*如果p的前驱为空时,把当前结点作为首结点,并令当前结点的后驱为p*/
i->prior=NULL;
p->prior=i;
*start=i;
return;
}
}
old->next=i; /*如果在整个链表都找不到name域比当前数据的name域大的结点,*把当前数据放在作为尾结点放在最后*/
i->next=NULL; /*令链表尾结点后驱批向当前结点,当前结点的后驱为空*/
i->prior=old; /*令当前结点的前驱为之前的最后结点*/
*last=i; /*尾结点取i地址*/
}
/*********************************************************
* 功能描述:删除函数
* 输入参数:struct address **start,struct address **last
* 输出参数: 无
* 返回值: 空
* 其它说明:消息字段之间用分号(;)分隔
************************************************************ */
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)
{
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");
}
}
/*********************************************************
* 功能描述:查找函数
* 输入参数: char *name
* 输出参数:无
* 返回值: 无
* 其它说明:消息字段之间用分号(;)分隔
************************************************************ */
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;
}
/*********************************************************
* 功能描述:输出整个链表
* 输入参数: address *info
* 输出参数: info->name,info->city,info->phone,info->state,info->zip
* 返回值: 无
* 其它说明:消息字段之间用分号(;)分隔
************************************************************ */
void list(void) /*输出整个链表*/
{
struct address *info;
info=start;
if(info==NULL)
printf("NO information!");
while(info)
{
display(info);
info=info->next;
}
printf("\n\n");
}
/*********************************************************
* 功能描述:输出传入结点函数
* 输入参数: 无
* 输出参数:info->name,info->city,info->phone,info->state,info->zip
* 返回值: 无
* 其它说明:消息字段之间用分号(;)分隔
************************************************************ */
void display(struct address *info) /*输出传入结点函数*/
{
printf("%s\n",info->name);
printf("%s\n",info->phone);
printf("%s\n",info->city);
printf("%s\n",info->state);
printf("%s\n",info->zip);
printf("\n\n");
}
/*********************************************************
* 功能描述:查找函数
* 输入参数: info->name
* 输出参数: info->name,info->city,info->phone,info->state,info->zip
* 返回值:无
* 其它说明:消息字段之间用分号(;)分隔
************************************************************ */
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; /*FILE的结构型指针管理文件读写*/
fp=fopen("mlist","wb"); /*生成文件使fp指向mlist文件,wb新建一个二进制文件,已存在的文件将被删除,只允许du*/
if(!fp)
{
printf("Cannot open file.\n");
return;
}
printf("\nSaveing ……\n");
info=start;
while(info) /*把链表写入文件*/
{
fwrite(info,sizeof(struct address),1,fp); /*将info写入到fp文件*/
info=info->next;
}
printf("-ok!\n");
fclose(fp); /*链表全部写入文件后,关闭文件*/
}
/*********************************************************
* 功能描述:装入函数
* 输入参数:无
* 输出参数:无
* 返回值: 无
* 其它说明:消息字段之间用分号(;)分隔
************************************************************ */
void load() /*调用预存文件函数*/
{
register int t, size;
struct address *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 address); /*为结点分配内存*/
start=(struct address*)malloc(size);
if(!start) /*如果读取失败,返回*/
{
printf("Error!\n");
exit(0);
}
info=start;
p=(char*)info;
while((*p++=getc(fp))!=EOF) /*如果从文件fp中读取的字节不结束*/
{
for(t=0;t<size-1;++t)
*p++=getc(fp); /*从文件中读取*/
info->next=(struct address*)malloc(size);
if(!info->next)
{
printf("Error!\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");
}
ll.h
/***********************************************************
*版权所有 (C)2016, Li Ling
* 文件名称:ll.h
* 文件标识:无
* 内容摘要:该代码用于获取满足后缀要求的第一个文件
* 其它说明:无
* 当前版本: V1.0
* 作 者:李玲
* 完成日期: 2016 12 28 *
* 修改记录0:
* 修改日期: 无
* 版本号: V1.0
* 修改人:Li Ling
* 修改内容:创建
**********************************************************/
struct address
{ /*定义结构*/
char name[30]; /*名字*/
char phone[100]; /*电话号码*/
char city[30]; /*城市*/
char state[30]; /*国家*/
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 load(); //装入
void list(); //显示信息
void mldelete(struct address **,struct address **); //删除信息
void dls_store(struct address *i,struct address **start,struct address **last);
void inputs(char *,char *,int);
void display(struct address *);
int menu_select(void);