设计内容通讯录.docx
- 文档编号:30421440
- 上传时间:2023-08-14
- 格式:DOCX
- 页数:23
- 大小:57.31KB
设计内容通讯录.docx
《设计内容通讯录.docx》由会员分享,可在线阅读,更多相关《设计内容通讯录.docx(23页珍藏版)》请在冰豆网上搜索。
设计内容通讯录
一.设计内容(通讯录)
本系统应完成一下几方面的功能:
1)?
输入信息——enter();
2)?
显示信息———display();
3)?
查找以姓名作为关键字———search();
4)?
删除信息———delete();
5)?
存盘———save();
6)?
装入———load();
设计要求:
1)?
每条信息至包含:
姓名(NAME)街道(STREET)城市(CITY)邮编(EIP)国家(STATE)几项
2)?
作为一个完整的系统,应具有友好的界面和较强的容错能力
二.设计思路
通过visualc++6.0(用的是C语言)编写一个dos界面的控制台程序,该程序通过链表的操作,文件存储来实现通讯录的基本功能
structaddress{/*定义结构*/
charname[10];/*姓名*/
charstreet[50];/*街道*/
charcity[10];/*城市*/
charstate[15];/*国家*/
chareip[7];/*邮编*/
structaddress*next;/*后继指针*/
structaddress*prior;/*前驱指针*/
}
链表的插入,删除来实现通讯录里的内容的插入删除
当操作完成通过文件件来存储链表的信息,下次打开程序时,读取文件里的内容到内存中,放在链表,然后又可以对链表进行操作;
在这里面,文件内容不可以在外部更改,只能通过读取到内存链表中,通过程序进行更改,然后再写入到文件,写入过程会覆盖上次的内容。
structaddress*start;/*首结点*/
structaddress*last;/*尾结点*/
structaddress*find(char*);/*声明查找函数*/
voidenter();/*函数声明*/
voidsearch();/*查找,查找过程中调用find函数*/
voidsave();/*存盘,将链表信息保存到文件中*/
voidload();/*导入,将文件内容导入到内存链表中*/
voidlist();/*显示当前链表中信息*/
voidddelete(structaddress**,structaddress**);
voidinsert(structaddress*i,structaddress**start,
structaddress**last);
voidinputs(char*,char*,int);
voiddisplay(structaddress*);
intmenu_select(void);
三.详细设计
1.主界面设计
通过switch语句调用各种函数,实现各种操作。
然后把switch嵌套到无限的for循环(for(;;))中,使完成每一步操作都回到到选择操作的主界面
voidmain()
{
start=last=NULL;
for(;;)/*无限循环*/
{
switch(menu_select())/*调用主界面的选择函数,带回返回值*/
{
case1:
enter();
continue;
case2:
ddelete(&start,&last);
continue;
case3:
list();
continue;
case4:
search();
continue;
case5:
save();
continue;
case6:
load();
continue;
case7:
exit(0);
}
}
}
intmenu_select(void)/*主目录*/
{
chars[80];
intc;
printf("………………^欢迎使用DOS通讯录系统^………………\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("\nPleaseenteryourchoice:
\n");
gets(s);
c=atoi(s);/*将获取的字符串转换成整型*/
}while(c<0||c>7);
returnc;/*返回输入值*/
}
2.输入信息函数
输入函数:
structaddress*info;/*定义当前结点*/
for(;;)
{
info=(structaddress*)malloc(sizeof(structaddress));/*为当前结点分配空间*/
if(!
info)
{
printf("\nOutofmemory");
exit(0);/*如果分配空间失败,退出程序*/
}
printf("输入空姓名结束:
\n");
inputs("请输入姓名:
",info->name,10);
if(!
info->name[0])break;/*如果输入姓名为空,结束循环*/
inputs("请输入街道:
",info->street,50);
inputs("请输入城市:
",info->city,15);
inputs("请输入国家:
",info->state,15);
inputs("请输入邮编:
",info->eip,7);
insert(info,&start,&last);/*调用结点插入函数*/
}
输入函数调用到另外两个函数,inputs和insert
其中inputs中还用到fgets(str,n,fp),把键盘的输入信息传到
字符串中
charp[255];
do
{
printf(prompt);
fgets(p,254,stdin);/*stdin,标准输入缓存,获取键盘输入信息*/
if(strlen(p)>count)
printf("\nTooLong\n");
}while(strlen(p)>count);
p[strlen(p)-1]=0;
strcpy(s,p);
insert是关键函数,每当输入完一条信息都会调用到insert函数,将信息插入到链表中
if(*last==NULL)/*如果尾结点为空,意味着当前链表为空*/
{/*则将该结点赋给头尾结点*/
i->next=NULL;
i->prior=NULL;
*last=i;
*start=i;
return;
}
else/*如果链表不为空,则将信息插入到链表尾,作为尾结点*/
{
(*last)->next=i;
i->prior=*last;
i->next=NULL;
*last=(*last)->next;
}
NULL
NULL
插入信息会显示在链表最后
3.删除·查找·显示函数
删除函数调用find函数,通过姓名,查找到该节点,然后删除该节点信息,这其中涉及到头尾节点,及其变化;
先判断是否为头结点,如果为头结点,则把原头结点的后继作为新的头结点
如果不为头结点,则该节点的前驱的next指向该节点的后继
如果该节点为尾结点,则让该节点的前驱作为新的尾结点
structaddress*info;
chars[80];
inputs("请输入姓名:
",s,10);
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;
if(info!
=*last)
info->next->prior=info->prior;
else
*last=info->prior;
}
free(info);
printf("-Ok,删除成功!
\n");
}
与删除相比,查找就简单的多,只需要调用find的函数,找到该节点记录并显示出来就行了,在search本身里面只要调整下输出的界面就行了
structaddress*find(char*name)/*查找函数,形参为欲查找结点的name域*/
{
structaddress*info;
info=start;
while(info)
{
if(!
strcmp(name,info->name))
returninfo;
info=info->next;
}
printf("Namenotfound.\n");
returnNULL;
}
输出函数更简单,直接输出链表即可
if(info==NULL)
printf("当前记录为空!
");
else
printf("姓名\t街道\t\t城市\t国家\t邮编\t\n");
while(info)
{
display(info);/*display为输出节点函数,一些列print组成*/
if(info->next==NULL)
{break;}info=info->next;
};
4.存储与导入
存储
存储时通过fopen打开文件(没有该文件时则创建)
fp=fopen("record.txt","wb");/*生成文件*/
if(!
fp)
{printf("Cannotopenfile.\n");return}
然后通过fwrite将链表信息写入文件
while(info)/*把链表写入文件*/
{fwrite(info,sizeof(structaddress),1,fp);
info=info->next;}
fwrite每次从info读取一个sizeof(structaddress)长度的数据,
写入fp文件中。
写入完毕后即关闭文件
fclose(fp);
导入
导入时先建立链表,为节点分配内存空间
然后打开文件,将文件的内容写入内存链表中
registerintt,size;
structaddress*info,*temp=0;
char*p;
FILE*fp;/*打开文件*/
if((fp=fopen("record.txt","r"))==NULL)
{
printf("Cannotopenfile!
\n");
return;
}
printf("\n\nLoading...\n");/*调用文件*/
size=sizeof(structaddress);/*为结点分配内存*/
start=(structaddress*)malloc(size);
if(!
start)/*如果读取失败,返回*/
{
printf("Outofmemory!
\n");
exit(0);
}
info=start;
p=(char*)info;
while((*p++=getc(fp))!
=EOF)
{
for(t=0;t *p++=getc(fp); info->next=(structaddress*)malloc(size); if(! info->next) { printf("Outofmemory! \n"); return; } info->prior=temp; temp=info; info=info->next; p=(char*)info; } temp->next=0; last=temp; start->prior=0; fclose(fp); 注意: 每次文件存储的时候都会覆盖以前存在文件里的内容,而每次导入的时候都会改变链表的内容。 因此每次打开程序时请先导入存储在文件里的数据,或者将record.txt备份存储起来,避免数据丢失。 四.设计总结 通过本次课程设计,我学到了很多东西。 以前从没有用过文件方面的知识,而这次设计中用到了,刚开始使用时出了很多问题,在文件存储时经常遇到意外错误而导致程序终止了。 这次的实验使我对结构体,链表的认识更深刻,使用更熟练,刚开始时在链表插入时遇到好多次内存方面的错误,还有插入操作时对指针的使用不太熟练。 通过一次次的思考与实验,思路更加清晰,程序的容错能力也越来越强。 这次实验让我学到很多书本上没有的东西。 程序里多次用到for(;;)循环,还有(structaddress*)malloc(sizeof(structaddress))为节点分配内存空间。 在文件操作中主要涉及到的函数有: fopen(”文件名”,”使用文件方式”); fwrite(info,sizeof(structaddress),1,fp); fclose(文件指针); 五.参考资料 C程序设计(第三版)谭浩强清华大学出版社 数据结构(C++版)李根强中国水利水电出版社 附完整源码: #include #include #include structaddress{/*定义结构*/ charname[10]; charstreet[50]; charcity[10]; charstate[15]; chareip[7]; structaddress*next;/*后继指针*/ structaddress*prior;/*前驱指针*/ }; structaddress*start;/*首结点*/ structaddress*last;/*尾结点*/ structaddress*find(char*);/*声明查找函数*/ voidenter();/*函数声明*/ voidsearch(); voidsave(); voidload(); voidlist(); voidddelete(structaddress**start,structaddress**last); voidinsert(structaddress*i,structaddress**start, structaddress**last); voidinputs(char*,char*,int); voiddisplay(structaddress*); intmenu_select(void); voidmain() { start=last=NULL; for(;;) { switch(menu_select()) { case1: enter(); continue; case2: ddelete(&start,&last); continue; case3: list(); continue; case4: search(); continue; case5: save(); continue; case6: load(); continue; case7: exit(0); } } } intmenu_select(void)/*主目录*/ { chars[80]; intc; printf("………………^欢迎使用DOS通讯录系统^………………\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("\nPleaseenteryourchoice: \n"); gets(s); c=atoi(s); }while(c<0||c>7); returnc;/*返回输入值*/ } voidenter()/*输入函数,本函数循环输入资料,当输入姓名为空时退出*/ { structaddress*info;/*定义当前结点*/ for(;;) { info=(structaddress*)malloc(sizeof(structaddress));/*为当前结点分配空间*/ if(! info) { printf("\nOutofmemory"); exit(0);/*如果分配空间失败,退出程序*/ } printf("输入空姓名结束: \n"); inputs("请输入姓名: ",info->name,10); if(! info->name[0]) break;/*如果输入姓名为空,结束循环*/ inputs("请输入街道: ",info->street,50); inputs("请输入城市: ",info->city,15); inputs("请输入国家: ",info->state,15); inputs("请输入邮编: ",info->eip,7); insert(info,&start,&last);/*调用结点插入函数*/ } } voidinputs(char*prompt,char*s,intcount)/*输入函数,有越界检测功能*/ { charp[255]; do { printf(prompt); fgets(p,254,stdin); if(strlen(p)>count) printf("\nTooLong\n"); }while(strlen(p)>count); p[strlen(p)-1]=0; strcpy(s,p); } voidinsert(/*数据插入函数*/ structaddress*i, structaddress**start, structaddress**last ) { if(*last==NULL)/*如果尾结点为空,意味着当前链表为空*/ { i->next=NULL; i->prior=NULL; *last=i; *start=i; return; } else { (*last)->next=i; i->prior=*last; i->next=NULL; *last=(*last)->next; } } voidddelete(structaddress**start,structaddress**last)/*删除函数*/ { structaddress*info; chars[80]; inputs("请输入姓名: ",s,10);/*输入欲删除结点的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,删除成功! \n"); } } structaddress*find(char*name)/*查找函数,形参为欲查找结点的name域*/ { structaddress*info; info=start; while(info) { if(! strcmp(name,info->name))returninfo;
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 设计 内容 通讯录