题目描述:以文本的方式保存用户录入的数据,并提供查询的功能共用户查询和使用通信录信息。
功能要求及说明:
通讯录要求实现最基本的功能,包括录入、删除、查找和修改,为此需要首先定义记录项的格式,其基本属性包括编号、姓名、性别、住址、联系电话等。整个系统由如下几大功能模块组成:
(1)通讯录的建立;该模块主要完成将数据存储工作。记录可以从文本文件中读入,也可以从键盘逐条输入记录。
(2)通讯录查询;用户可以按照联系人的姓名或电话号码查询。若查到,则显示该记录的信息;否则,显示查找失败的提示信息。
(3)通讯录的维护;实现对记录的修改、删除、插入和排序等操作。
(4)通讯录的输出;实现屏幕显示和将记录信息写入文本文件中.
(5)采用模块化设计。
以上功能请以菜单形式与用户进行交互
1、数据类型的定义及含义:
(1)结构体类型data,用来描述每个学生的基本属性(学号、姓名、性别、地址、电话号码)。
(2)链表类型Link *L,表示以L为头结点的单链表,用来描述整个通讯录学生之间的关系,用单链表来存储数据元素信息。
(3)文件指针类型 FILE *fp;用来操作文件,指向文件中的字符。
2、主函数调用的函数的定义:
(1)void CreatLink(Link *L); //创建通讯录,调用了2个函数,
(2)void CreateLInk_from_file(Link*L); //从文本文件中读入
(3)voidCreatLink_fromkeybord(Link* L); //从键盘逐条输入记录
(4)voidSearchLink(Link *L); //查询通讯录
(5)voidFind_SNum(Link *L); //按编号查询
(6)voidFind_SName(Link *L); //按姓名查询
(7)voidFind_STel(Link *L); //按电话号码查询
(8)void ChangeLink(Link*L);//修改通讯录
(9)voidDeleteLink(Link *L);//删除通讯录
(10)voidDestoryLink(Link *L);//销毁线性表
(11)voidInsertLink(Link *L);//插入通讯录
(12)voidSort_Link(Link *L); //通讯录排序,按照编号,冒泡法
(13)voidDeletesameSum(Link *L); //删除通讯录相同的编号的结点
(14)voidPrintLink(Link *L);//显示到显示器上
(15)voidSave(Link *L);//保存到文件telbook.txt
(16)void Clear();//清屏函数
2、简要的主程序流程:
|
四 详细设计
1、流程图:
|
2、数据的实现及定义:
struct node
{ //通讯录结点数据域
charSnum[20]; //编号
charSname[10];//姓名
charSsex[10]; //性别
charSaddr[20];//地址
charStelenum[20];//电话号码
};
typedef struct node telebook;
struct Lnode
{
telebookdata; //结点数据域
structLnode *next; //结点指针域
};
typedef struct Lnode Link;
Link *L;//创建头节点
3、函数的实现
(1)在mian函数中先建立一个空表,链表的表头为L,显示菜单到窗口,提示用户输入choice,通过choice进入各个子菜单,进而对通讯录进行相关操作:
main()
{
char chioce; //进入子菜单
L=(Link*)malloc(sizeof(Link));
L->next=NULL; //先建立一个空表,通讯录建立就是尾插法
…Menu();//调用Menu()函数
…CreateLink(L);
//通过chioce
}
(2)Menu函数就是将此通讯录管理系统的所有功能显示到窗口,便于用户更好的和此系统进行交互:
void Menu()//菜单
{
printf(…);
…
}
(3)CreateLink通讯录的建立,两种方式建立通讯录:直接从键盘输入、从文本文件中读入。通讯录的建立不管是从键盘直接输入还是从文本输入;都可以看成在单链表的尾部插入新的结点:
void CreateLink(Link*L) //通讯录的建立,传递的是链表的头结点
{…
if(n==1) {CreatLink_fromkeybord(L); … //调用CreatLink_fromkeybord函数
if(n==2) {CreateLInk_from_file(L);… //调用CreateLInk_from_file函数
}
(4)CreateLink函数传递的是单链表的头结点,L是不可以改变的;从文本文件中读入建立通讯录,首先找到单链表的尾结点,然后将新的结点插入到链表的最后。将文本文件内容读入到相应的链表中去,使用的是fscanf函数,之所以能够依次读入到相应的结点中去是因为fscanf函数字符串读出函数,遇到空格或者换行就会写入到相应的结点的数据域中:
void CreateLink (Link*L) //从文本文件中读入,建立通讯录
{
p=L; //头结点赋值给点P,头结点是不可以移动的
q=(Link*)malloc(sizeof(Link)); //指向链表的任意一个结点
while(p->next!=NULL )
{
p=p->next;
} //找到链表的尾,利用尾插法
while(fscanf(fp,"%s %s%s %s%s\n",q->data.Snum,q->data.Sname,q->data.Ssex,q->data.Stelenum,q->data.Saddr)!=EOF) //文件读入到链表
{
q->next=NULL;
&nb