通讯录查询系统课程设计.docx
《通讯录查询系统课程设计.docx》由会员分享,可在线阅读,更多相关《通讯录查询系统课程设计.docx(28页珍藏版)》请在冰豆网上搜索。
![通讯录查询系统课程设计.docx](https://file1.bdocx.com/fileroot1/2022-11/30/459636e2-8677-4cc7-b86d-55f4ce65d624/459636e2-8677-4cc7-b86d-55f4ce65d6241.gif)
通讯录查询系统课程设计
《数据结构》课程设计报告
信息工程学院
计算机科学与技术专业
单位员工通讯录管理系统(线性表应用)
计算机093班第2组
组员:
姓名:
林鸿学号:
**********
姓名:
张明学号:
**********
姓名:
周龙学号:
**********
指导教师:
***
日期:
2011年1月2日
程序设计书目录
一、程序设计目标
二、问题描述
三、需求分析(说明课程设计的任务)
四、概要设计(说明课程设计中用到的抽象数据类型的定义、主程序的流程以及各程序模块之间的调用关系等)
五、详细设计(实现程序模块的具体算法)
六、软件说明书(给出软件应如何使用,使用时的具体事项)
七、源程序清单(要求400行以上,要有注释说明)
八、测试报告(调试过程中遇到的问题以及解决方法,并列出测试结果,包括输入和输出)
九、课程设计总结
一:
程序设计目标
通过对通讯录管理链表的课程设计,加深对程序设计的理解,熟练掌握和加深c语言的基本知识和语法规范,同时更进一步地理解数据结构对单链表知识的应用,培养我们调查研究、查阅技术文献、资料、手册以及编写程序的能力,同时也考验我们善于思考,互相帮助的团队精神。
本程序是学会建立通讯录,使人员之间联系更加方便快捷,增加办事效率。
二:
问题描述
为某个单位建立一个员工通讯录管理系统,可以方便查询每一个员工的办公室电话、手机号及电子邮箱。
其功能包括通讯录链表的建立、员工通讯信息的查询、修改、插入与删除、以及整个通讯录的输出。
三:
需求分析
想要建立一个单位员工通讯录的管理系统,方便查询其每个员工的一些信息。
首先,应运用c语言中结构体的知识。
把员工的各项信息储存到结构体的链表中,定义一个新的结构体类型struct(struct是声明结构体时所必须使用的关键字)它向编译系统声明这是一个“结构体类型”,它包括num,name,phone等不同类型的数据项。
其次:
运用数据结构中线性表的知识。
线性表的存储结构分为线性表的线性存储结构和线性表的链式存储结构,线性表的顺序存储结构是指用一组地址连续的存储单元一次存储线性表的数据元素。
线性表的链式存储结构则是通过指针反映元素之间的关系,不要求逻辑上相邻的元素在物理位置上也相邻,所以该方法可以克服顺序表的一些缺点。
所以本题应运用线性链表的链式存储结构。
线性链表的链式存储结构又分为单链表、循环链表和双链表,本题运用单链表的知识。
1:
通讯录链表的建立。
建立单链表有两种方法,头插入法和尾插入法。
头插入法是将每次新插入的结点插入在链表的表头,而尾插入法是将新插入的结点插入到链表的表尾。
在这个通讯录的建立中将采用尾插入法建立链表。
2:
链表的插入。
链表结点的插入是要求将一个通讯录数据结点按其编号的顺序插入有序通讯录表的相应位置,以保持其有序性。
使用两个指针变量分别指向刚访问的结点和下一个结点,寻找插入结点的位置,其中一个指向待插入位置的前一个结点。
3:
单链表的删除。
输入要查找的通讯录的编号或者姓名,从表头顺序访问表中结点,查找成功则返回指向查找的通讯者信息的结点,删除结点即可。
4:
链表的查询。
首先输入要查找的通讯录的编号、姓名、办公室电话号或手机号码,从表头顺序访问表中结点,查找成功则返回指向查找的通讯者信息的结点,否则返回一个空的指针。
5:
通讯录的输出。
将表头指针赋给一个指针变量,然后用其向后扫描,直至表尾,指针为空为止。
6:
员工信息的修改。
首先通过链表的查询找到要修改的结点,找到后就可以对员工的姓名、办公室电话号码、手机号码、电子邮箱任意一项进行改。
四:
概要设计
(1)本程序主要应用了结构体、指针,函数调用,和单链表的有关知识。
定义通讯者的结点类型:
typedefstruct{
charnum[5];//员工编号
charname[15];//员工姓名
charphone[15];//员工办公室电话号码
charcall[15];//员工手机号码
chare_mail[30];//员工电子邮箱
}DataType;
线性表的链式存储结构定义:
typedefstructnode//结点类型定义
{
DataTypedata;//结点数据
structnode*next;//结点指针域
}Dnode;
Dnode*head;//定义指向单链表的头指针
Dnode*p;//定义一个指向结点的指针变量
函数声明:
intmenu();//主菜单
Dnode*createlist();//创建
voidAdd(Dnode*head,Dnode*p);//插入
Dnode*research(Dnode*head);//查找
voidDelete(Dnode*head);//删除
Dnode*Change(Dnode*head,chark[]);//修改
voidprintlist(Dnode*head);//输出
voidSaveandfree();/*保存到文件*/
voidOpen();/*打开文件*/
(2)进入菜单选择函数,有0-6可以选择,选择1,则调用尾插入法建立通讯录链表函数Dnode*CreateList();选择2,则调用通讯录链表head中插入结点函数voidAdd(Dnode*head,Dnode*p);选择3,则调用通讯录链表上结点的删除函数voidDelete(Dnode*head);选择4,则调用有序通讯录链表上的查找函数Dnode*research(Dnode*head),选择5,则调用通讯录链表的输出函数voidPrint_List(Dnode*head);选择6,则调用修改员工信息函数Dnode*Change(Dnode*head,chark[]);选择0,则调用保存并退出系统函数,整个程序流程结束。
五.详细设计
首先应编写一个菜单程序。
intmenu()
{
inti;
printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
printf("\n");
printf("通讯录系统清单\n");
printf("\n");
printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
printf("\n");
printf("1.通讯录的建立");
printf("\n");
printf("2.添加人员信息");
printf("\n");
printf("3.删除人员信息");
printf("\n");
printf("4.查询人员信息");
printf("\n");
printf("5.输出人员信息");
printf("\n");
printf("6.修改人员信息");
printf("\n");
printf("0.退出并保存");
printf("\n");
printf("请选择0-6:
");
scanf("%d",&i);
while(i<0||i>6)
{
printf("系统提示:
您输入错误!
\n");//提示输入是否错误
printf("请重新输入0-6:
");
scanf("%d",&i);
printf("\n\n");
}
returni;
}
然后主函数调用返回值i,再到switch语句中进行相应的选择,进行模块处理。
Open();
while
(1)
{
switch(menu())
{
case1:
printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
printf("\n");
printf("通讯录链表的建立");
printf("\n");
printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
printf("\n");
//建立通讯录链表的函数调用
head=createlist();
break;
case2:
p=(Dnode*)malloc(sizeof(Dnode));
printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
printf("\n");
printf("通讯者信息的添加");
printf("\n");
printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
printf("\n");
printf("员工编号:
\n");
scanf("%s",p->data.num);
printf("员工姓名:
\n");
scanf("%s",p->data.name);
printf("员工办公室电话号码:
\n");
scanf("%s",p->data.phone);
printf("员工手机号码:
\n");
scanf("%s",p->data.call);
printf("员工电子邮箱:
\n");
scanf("%s",p->data.e_mail);
printf("操作已成功!
\n");
Add(head,p);
break;
case3:
printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
printf("\n");
printf("通讯录信息的删除");
printf("\n");
printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
printf("\n");
//通讯者删除函数的调用
Delete(head);//删除结点
break;
case4:
printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
printf("\n");
printf("通讯录信息的查询");
printf("\n");
printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
printf("\n");
//通讯者查询函数的调用
p=research(head);
if(p!
=NULL)
{
printf("编号姓名办公室电话手机号码邮箱");
putchar('\n');
printf("%-5s\t",p->data.num);
printf("%-10s\t",p->data.name);
printf("%-10s\t",p->data.phone);
printf("%-10s\t",p->data.call);
printf("%-15s\t\n",p->data.e_mail);
printf("\n");
}
else
printf("对不起没有您要查询者的信息\n");
break;
case5:
printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
printf("\n");
printf("通讯录的输出");
printf("\n");
printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
printf("\n");
//通讯录链表输出函数调用
print_list(head);
break;
case6:
{
charc=getchar();
charb[5];
printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
printf("\n");
printf("通讯录的修改");
printf("\n");
printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
printf("\n");
Change(head,b);
}
break;
case0:
Saveandfree();/*保存并释放内存*/
exit(0);break;
}
}
第三步是模块的分步处理,其中分为通讯录链表的建立、插入、删除、查询、输出、修改、退出。
六、软件说明书(给出软件应如何使用,使用时的具体事项)
打开开始菜单找到VC++6.0,打开此软件,用鼠标单击文件菜单里的打开选项,导入文件,按ctrl+f7,看文件是否有错误,如果没有错误按ctrl+f5进行运行。
首先在运行程序是弹出菜单供我们进行选择
1•通讯录的建立
2•添加人员信息
3•删除人员信息
4•查询人员信息
5•输出人员信息
6•修改人员信息
0•退出并保存
这里我们先选择1进行通讯录的建立,会出现我们要建立的内容。
请输入编号:
请输入姓名:
请输入办公室电话:
请输入手机号码:
请输入电子邮箱:
我们根据提示,进行相应的填写即可。
填写完毕后,系统会提示“要继续创建请按(n),结束创建请按其它键”如果我们选择n则继续进行编写。
然后我们可以选择2,进行通讯录链表的插入,过程同建立相似。
如果我们选择3,就进行通讯录链表的删除,这里我们可以按编号删除,也可以按姓名删除,只需要填写要删除人的编号或者姓名就可以删除该人的信息内容。
如果我们选择4,就进行通讯录链表的查询,其中也分为按编号和姓名、办公室电话、手机号码查询四种。
如果我们选择5,则输出全部人员内容的清单。
如果我们选择6,就进行结点信息的修改。
修改先是通过查找函数找到要修改的信息,在对找的的信息进行修改,修改的内容包括:
姓名、办公室电话号码、手机号码、电子邮箱。
六、源程序清单(要求400行以上,要有注释说明)
#include
#include
#include
//定义结构体变量
typedefstruct
{
charnum[5];
charname[15];
charphone[13];
charcall[15];
chare_mail[30];
}datatype;
//结点类型定义
typedefstructnode
{
//结点数据域
datatypedata;
//结点指针域
structnode*next;
}Dnode;
Dnode*head;
Dnode*p;
typedefstructnodelinklist;
//linklist*Head=NULL;
//菜单函数
intmenu();
//创建通讯单链表函数
Dnode*createlist();
//插入函数
voidAdd(Dnode*head,Dnode*p);
//查找函数
Dnode*research(Dnode*head);
//删除函数
voidDelete(Dnode*head);
//显示所有信息函数
voidprint_list(Dnode*head);
//修改信息
Dnode*Change(Dnode*head,chark[]);
voidSaveandfree();/*保存到文件*/
voidOpen();/*打开文件*/
//菜单函数
intmenu()
{
inti;
printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
printf("\n");
printf("通讯录系统清单\n");
printf("\n");
printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
printf("\n");
printf("1.通讯录的建立");
printf("\n");
printf("2.添加人员信息");
printf("\n");
printf("3.删除人员信息");
printf("\n");
printf("4.查询人员信息");
printf("\n");
printf("5.输出人员信息");
printf("\n");
printf("6.修改人员信息");
printf("\n");
printf("0.退出并保存");
printf("\n");
printf("请选择0-6:
");
scanf("%d",&i);
while(i<0||i>6)
{
printf("系统提示:
您输入错误!
\n");//提示输入是否错误
printf("请重新输入0-6:
");
scanf("%d",&i);
printf("\n\n");
}
returni;
}
//尾插法建立带头结点的通讯录链表算法
Dnode*createlist()
{
Dnode*head=(Dnode*)malloc(sizeof(Dnode));//申请头结点
Dnode*p;
Dnode*rear;
charc='n';
//尾指针初始指向头结点
rear=head;
while(c=='n')
{
p=(Dnode*)malloc(sizeof(Dnode));
printf("请输入编号:
\n");
scanf("%s",p->data.num);
printf("请输入姓名:
\n");
scanf("%s",p->data.name);
printf("请输入办公室电话:
\n");
scanf("%s",p->data.phone);
printf("请输入手机:
\n");
scanf("%s",p->data.call);
printf("请输入电子邮箱:
\n");
scanf("%s",p->data.e_mail);
//新结点连接到尾结点之后
rear->next=p;
//尾指针指向新结点
rear=p;
printf("要继续创建请按(n),结束创建请按其它键:
\n");
//读入一个标志数据
scanf("%c",&c);
}
//终端结点指针域置空
rear->next=NULL;
//返回链表头指针
returnhead;
}
//插入函数
voidAdd(Dnode*head,Dnode*p)
{
Dnode*p1;
Dnode*p2;
p1=head;
p2=p1->next;
while(p2!
=NULL&&strcmp(p2->data.num,p->data.num)<0)
{
//p1指向刚访问过的结点
p1=p2;
//p2指向表的下一个结点
p2=p2->next;
}
//插入p所指向的结点
p1->next=p;
//连接表中剩余部分
p->next=p2;
}
voidDelete(Dnode*head)
{
chara,b;
Dnode*p;
Dnode*q;
charnum[5];
charname[10];
intx;
printf("1.按编号删除\n");
printf("2.按姓名删除\n");
printf("请选择(1或2):
");
p=head->next;
scanf("%d",&x);
if(x==1)
{
printf("请输入要查询者的编号:
");
scanf("%s",num);
while(p&&strcmp(p->data.num,num)<0)
p=p->next;
if(p==NULL||strcmp(p->data.num,num)>0)
p=NULL;
}
if(x==2)
{
printf("请输入要查询者的姓名:
");
scanf("%s",name);
while(p&&strcmp(p->data.name,name)!
=0)
p=p->next;
}
scanf("%c",&b);
if(p==NULL)
{
printf("对不起没有您要查询者的信息\n");
return;
}
printf("要删除该结点吗?
(y/n):
");
scanf("%c",&a);
if(a=='y'||a=='Y')
{
q=head;
while(q!
=NULL&&q->next!
=p)
q=q->next;
//删除结点
q->next=p->next;
//释放被删除的结点空间
free(p);
printf("通讯者已经被删除\n");
}
}
//通讯链表上的查找
Dnode*research(Dnode*head)
{
Dnode*p;
charnum[5];
charname[10];
charphone[15];
charcall[15];
intx;
printf("1.按编号查询:
\n");
printf("2.按姓名查询:
\n");
printf("3.按电话号码查询:
\n");
printf("4.按手机号码查询:
\n");
printf("请选择(1-4):
");
p=head->next;//有头结点
scanf("%d",&x);
if(x==1)
{
printf("请输入要查询者的编号:
");
scanf("%s",num);
while(p&&strcmp(p->data.num,num)<0)
//要查找的编号值大于开始结点值
p=p->next;
if(p==NULL||strcmp(p->data.num,num)>0)
//没有查到要查找的通讯者
p=NULL;
}
if(x==2)
{
printf("请输入要查询者的姓名:
");
scanf("%s",name);
while(p&&strcmp(p->data.name,name)!
=0)
p=p->next;
}
if(x==3)
{
printf("请输入要查询者的办公室电话号码:
");
scanf("