简单通讯录c课程设计doc.docx

上传人:b****5 文档编号:8073915 上传时间:2023-01-28 格式:DOCX 页数:30 大小:243.19KB
下载 相关 举报
简单通讯录c课程设计doc.docx_第1页
第1页 / 共30页
简单通讯录c课程设计doc.docx_第2页
第2页 / 共30页
简单通讯录c课程设计doc.docx_第3页
第3页 / 共30页
简单通讯录c课程设计doc.docx_第4页
第4页 / 共30页
简单通讯录c课程设计doc.docx_第5页
第5页 / 共30页
点击查看更多>>
下载资源
资源描述

简单通讯录c课程设计doc.docx

《简单通讯录c课程设计doc.docx》由会员分享,可在线阅读,更多相关《简单通讯录c课程设计doc.docx(30页珍藏版)》请在冰豆网上搜索。

简单通讯录c课程设计doc.docx

简单通讯录c课程设计doc

C++课程设计

——简单通讯录管理

0411204班

041120431

董力

1.程序菜单功能

通讯录是一个简单的数据库库表,每一个记录(结点)包含个人所有通讯信息。

程序执行过程为:

显示主菜单,用户在choice:

处输入选项(按照功能列表输入1~9中的一个数字),按回车后执行相应的功能。

具体函数的功能请见下面4.提供典型测试数据组

2.分析,感想。

(1)、数据结构

程序采用一个单向链表类结构实现,每个结点代表一个通讯记录,链表类实现通讯录多个记录的管理工作。

(2)、新增功能

可批量输入,一次输入多个人的信息。

(3)、遇到的问题

这次课设遇到的问题较多,首先就是学过的知识无法融会贯通。

在完成课设时,许多知识点需要翻书查找(比如在输入输出流的部分),有时需要请教他人。

其次,是程序十分长,而且自己小错误不断,这样检查起来非常麻烦。

所以当运行程序时,出现了102个错误,其中大部分不是算法的问题,而是像少了“;”或是if中判断是否相等时用“=”而不是“==”。

最后,程序较长,编辑起来费力,有时一个算法出问题,其后的几个函数连带都会出问题,而且编译时没有显示有错误,这让检查起来非常麻烦,需要一遍又一遍阅读,有时还要请教别人一起阅读,耗时很长。

(4)、感想

这次课设成功完成,让我非常惊讶。

平时作业的一个程序,有时需要一个下午来完成。

现在,我发现原来我也可以完成如此复杂的程序。

更重要的是,这次课设让我的一些知识能记得更加深刻,对于编程也更加熟练。

而且,我知道请教他人的重要性,有时自己一个人想不出来的问题,问问同学,可以更好更快的解决。

最后,我知道了光把理论知识还不够,还要不断实践,这样才能将知识掌握得更加牢固,更加灵活。

3.提供有注释的源程序

#include

#include

#include

#include

#include

#include

classNode

{

charName[10];//姓名

intOfficePhone;//办公室电话

intHomePhone;//家庭电话

charMobilePhone[15];//手机号码

charE_Mail[20];//电子邮箱地址

Node*Next;//下一个结点指针

public:

Node(charna[]="sb",intop=0,inthp=0,charmp[]="0",charem[]="0")//构造函数,有缺省值

{

strcpy(Name,na);//将na中的姓名拷贝到Name中

OfficePhone=op;//将op中的数值赋给OfficePhone

HomePhone=hp;//将hp中的数值赋给HomePhone

strcpy(MobilePhone,mp);//将mp中的字符串拷贝到MobilePhone中

strcpy(E_Mail,em);//将em中的字符串拷贝到E_Mail中

}

voidShow()//显示结点数据

{

cout<<'\t'<

}

voidprint(ofstream&out)//将结点数据写入文件

{

out.open("addresslist.text");//打开名为"addresslist.text"的文档

out<<'\t'<

out.close();//关闭文档

}

voidSetName(charna[])//修改姓名

{

strcpy(Name,na);

}

voidSetOfficePhone(intop)//修改办公室电话

{

OfficePhone=op;

}

voidSetHomePhone(inthp)//修改住宅电话

{

HomePhone=hp;

}

voidSetMobilePhone(charmp[])//修改手机号码

{

strcpy(MobilePhone,mp);

}

voidSetE_Mail(charem[])//修改电子邮箱地址

{

strcpy(E_Mail,em);

}

friendclassAddressList;//将AddressList类说明为友元类

};

classAddressList

{

Node*HeadPtr;//链表首指针

Node*TailPtr;//链表尾指针

intTag;//排序状态标志

public:

AddressList()//构造函数,创建空链表,将Tag的值置为1

{

HeadPtr=NULL;//设置首指针的初始值为空

TailPtr=NULL;//设置尾指针的初始值为空

Tag=1;//Tag的初始值为1

}

voidAddTail(Node*p)//将p指向的结点加入到链表的尾部

{

if(HeadPtr==NULL)//如果链表为空,将数据添加在第一条

{

HeadPtr=TailPtr=p;//链表为空,首尾指针均指向p

}

else

{

TailPtr->Next=p;//如果不为空,则尾指针的Next指向p

TailPtr=p;//将p的值赋给TailPtr

TailPtr->Next=NULL;//使TailPtr的成员Next为空

}

}

voidAddSort(Node*p)//将p指向的结点按Tag指定的顺序插入到链表中

{

if(HeadPtr==NULL)//当链表为空时

{

HeadPtr=TailPtr=p;//直接将数据记录在第一条

p->Next=NULL;

}

else//如果链表不为空

{

Node*p1=HeadPtr,*p2=HeadPtr;//定义两个Node型指针变量

if(Tag==1)//按姓名排列

{

p1=HeadPtr;//将首指针赋给p1

while(strcmp(p->Name,p1->Name)>0&&p1->Next!

=NULL)//比较p中Name和p1中的大小

{

p2=p1;p1=p1->Next;

}//如果p大,就将下一个数据赋给p1,否则跳出循环

if(strcmp(p->Name,p1->Name)<=0)//如果p的成员Name比较小

{

p->Next=p1;//将p的下一个指向p1

if(HeadPtr==p1)HeadPtr=p;//如果首指针等于p1,则将p的值赋给首指针

elsep2->Next=p;

}//如果p1是第一个将p赋给HeadPtr,否则p2下一个指向p

else//如果找不到比p的Name小的数据,就将p插在链表末尾

{

p1->Next=p;//将p赋给p的下一条记录

p->Next=NULL;//而p的下一条为空

}

}

if(Tag==2)//按办公室电话排列,同按姓名排列的方法

{

p1=HeadPtr;

while((p->OfficePhone)>(p1->OfficePhone)&&p1->Next!

=NULL)

{

p2=p1;p1=p1->Next;

}

if((p->OfficePhone)<=(p1->OfficePhone))

{

p->Next=p1;

if(HeadPtr==p1)HeadPtr=p;

elsep2->Next=p;

}

else

{

p1->Next=p;

p->Next=NULL;

}

}

if(Tag==3)//按家庭电话排列,同按姓名排列的方法

{

p1=HeadPtr;

while((p->HomePhone)>(p1->HomePhone)&&p1->Next!

=NULL)

{

p2=p1;p1=p1->Next;

}

if((p->HomePhone)<=(p1->HomePhone))

{

p->Next=p1;

if(HeadPtr==p1)HeadPtr=p;

elsep2->Next=p;

}

else

{

p1->Next=p;

p->Next=NULL;

}

}

if(Tag==4)//按手机号码排列,同按姓名排列的方法

{

p1=HeadPtr;

while(strcmp(p->MobilePhone,p1->MobilePhone)>0&&p1->Next!

=NULL)

{

p2=p1;p1=p1->Next;

}

if(strcmp(p->MobilePhone,p1->MobilePhone)<=0)

{

p->Next=p1;

if(HeadPtr==p1)HeadPtr=p;

elsep2->Next=p;

}

else

{

p1->Next=p;

p->Next=NULL;

}

}

if(Tag==5)//按电子邮箱地址排列,同按姓名排列的方法

{

p1=HeadPtr;

while(strcmp(p->E_Mail,p1->E_Mail)>0&&p1->Next!

=NULL)

{

p2=p1;p1=p1->Next;

}

if(strcmp(p->E_Mail,p1->E_Mail)<=0)

{

p->Next=p1;

if(HeadPtr==p1)HeadPtr=p;

elsep2->Next=p;

}

else

{

p1->Next=p;

p->Next=NULL;

}

}

}

}

Node*LookUp(char*name)//按姓名查找结点,返回该结点指针

{

Node*p=HeadPtr;//定义一个Node型指针,初始值为HeadPtr

while(p!

=NULL)//当链表不为空时

{

if(strcmp(p->Name,name)==0)//循环比较数据中的Name成员

returnp;//如果存在,返回结点

p=p->Next;//将p的下一组数据赋给p

}

returnNULL;//如果不存在,返回值为空

}

voidDelete(char*name)//删除指定姓名的结点

{

Node*p1,*p2;

if(HeadPtr==NULL)//当链表为空时

{

cout<<"通讯录为空,无结点可删!

\n";

}

p1=HeadPtr;

while(strcmp(p1->Name,name)!

=0&&p1->Next!

=NULL)//查找所在位置

{

p2=p1;//将p1的值赋给p2

p1=p1->Next;//p1指向下一条记录

}

if(strcmp(p1->Name,name)==0)//若找到该姓名对应的数据,删除该数据

{

if(p1==HeadPtr)//如果p1在第一条,则将首指针指向下一条记录,将p1空出

HeadPtr=p1->Next;

else//否则将p1的上一个记录的成员Next直接指向p1的下一条记录

p2->Next=p1->Next;

deletep1;//释放p1的空间

cout<<"删除了一个数据!

\n";

}

else//若找不到,则输出"通讯录上没找到该条记录!

"

cout<

\n";

}

voidDeleteAll()//删除链表中全部结点

{

Node*p;//定义一个Node型指针变量p

while(HeadPtr)//当首指针不为0时,进行循环

{

p=HeadPtr;//将head赋给p

HeadPtr=HeadPtr->Next;//将head的下一条数据赋给head

deletep;//释放p的空间

}

}

voidSort(inttag)//按Tag指定的关键字重新排序

{Tag=tag;//将tag的值赋给Tag

Node*p1,*p;//定义两个Node型指针变量p1,p

p=HeadPtr;//将首指针的值赋给p

HeadPtr=NULL;//将首指针置为空

while(p)//当首指针不为空时,进行循环

{p1=p;//将p的值赋给p1

p=p->Next;//p指向下一条记录

p1->Next=NULL;//p1的成员Next指向空

AddSort(p1);//调用公有成员函数,将p1重新按关键字排序

}

}

voidShowAll()//显示全部结点,每10个显示一屏

{

Node*p=HeadPtr;//定义一个Node型指针p,初始化为首指针的值

inti=1;//定义一个整型变量,计算现实的数据个数

system("cls");//清屏

while(p)//当p不为空时,进行循环

{cout<

p->Show();//循环输出数据p

p=p->Next;//将下一条记录的值赋给p

if(!

(i++%10))//当i是10的倍数时,暂停程序并清屏

{system("pause");

system("cls");

}

}

}

voidSetTag(intt)//重置Tag的值

{

Tag=t;

}

intGetTag()//获取Tag的值

{

return(Tag);//返回Tag的值

}

intCount()//计算链表中有多少个结点

{

Node*p;//定义一个Node型指针p

intt=0;//定义一个整型变量t,用来计算链表中结点的个数

p=HeadPtr;//将首指针的值赋给p

while(p->Next!

=NULL)//当链表不为空时

{

t=t+1;//每当数据不为空时,t就加1

p=p->Next;//p指向下一条记录

}t=t+1;//因为当p->Next=NULL是就退出程序,所以末尾t要加1

returnt;//返回t

}

Node*GetHeadPtr()//获取链表首指针

{

returnHeadPtr;//返回首指针

}

~AddressList()//析构函数,释放链表空间

{Node*p;//定义一个Node型的指针变量

while(HeadPtr!

=NULL)//链表不为空,进行循环

{

p=HeadPtr;//将第一条数据赋给p

HeadPtr=HeadPtr->Next;//将下一条数据赋给首指针

deletep;//释放p的空间

}

}

#defineLensizeof(classNode)//定义常量Len为Node类数据的长度

voidCreateList(char*filename)//从二进制文件中读入数据,构造链表

{

Node*p[100];//定义一个有100个数据空间的指针数组

inti=0,j=0;//定义两个整型变量,来记录第几条数据和读取数据的个数

fstreamfile(filename,ios:

:

in|ios:

:

binary);//定义一个文件流对象

if(!

filename)//当文件为空时,无法打开

{

cout<<"不能打开文件:

"<

exit

(1);

}

file.read((char*)&Tag,sizeof(int));//从文件中读取Tag

file.read((char*)&j,sizeof(int));//从文件中读取数据的个数

p[0]=newNode;//申请一个p的动态存储空间

while(file.read((char*)p[i],Len)!

=0)//从文件中读取Len长度的数据不为0

{

p[i+1]=newNode;

AddSort(p[i+1]);//调用公有成员函数AddSort(),将文件中数据读取后,重新排序

}

file.close;//关闭文件

}

voidWriteToFile(char*filename)//将链表中的数据写入指定的二进制文件

{

Node*p;//定义一个Node型的指针变量

p=HeadPtr;//将首指针的值赋给p

fstreamfile(filename,ios:

:

in|ios:

:

binary);//定义一个文件流对象

if(!

filename)//当文件为空时,无法打开文件

{

cout<<"不能打开文件:

"<

exit

(1);

}

while(p!

=0)//当数据不为0时,将数据写入文件中

{

file.write((char*)p,Len);//将p写入文件中

p=p->Next;

}

file.close;//关闭文件

}

voidouttxt(char*file)//将数据从文件file导出

{Node*p=HeadPtr;//定义一个Node型指针变量,初始值为HeadPtr

intn=1;//定义一个整型变量,作为数据的序号

fstreamout(file,ios:

:

out);//以写入的方式打开正文文件

if(!

out)//定义一个输出文件流对象

{cout<<"不能打开该文件:

"<

exit

(1);

}

while(p)

{out<

p=p->Next;

}

out.close();

}

 

};

intmenu_select()//菜单实现

{

char*a[]={"1.AddRecord","2.DeleteRecord","3.DisplayAllRecord","4.Query",

"5.ModifyRecord","6.AddfromaTextFile","7.WritetoaTextFile",

"8.Sort","9.DeletAll","0.Quit",NULL};//将菜单的选项赋给数组

inti,choice;//定义两个整型变量,一个用于输出选项,一个用于选择,并调用相关函数

do{

system("cls");

cout<<"\n\n========AddressBookManagingSyetem========\n\n";

for(i=0;a[i];i++)//循环输出选项

cout<

cout<<"\n================================================\n";

cout<<"Input1-9,0:

";

cin>>choice;//输入choice

}while(choice<0||choice>9);//在0到9的菜单中做出选择

return(choice);//返回所选的值

}

voidadd(AddressList&addrlist)//增加记录

{

Node*p[50];//一次需要输入的数据

charn[100],m[100],o[100];//姓名,手机,电子邮箱

intq,r;//办公和家庭电话

inti,j;

cout<<"请输入本次需要输入的数据的个数(0~100):

";

cin>>j;

cout<<"请依次输入姓名、办公电话、家庭电话、手机号码和电子邮箱地址:

";

for(i=0;i

{

cin>>n>>q>>r>>m>>o;//输入数据的各个成员

p[i]=newNode;//申请动态存储空间

p[i]->SetName(n);//调用公用成员函数,修改姓名

p[i]->SetOfficePhone(q);//调用公用成员函数,修改办公电话

p[i]->SetHomePhone(r);//调用公用成员函数,修改家庭电话

p[i]->SetMobilePhone(m);//调用公用成员函数,修改手机

p[i]->SetE_Mail(o);//调用公用成员函数,修改电子邮箱

addrlist.AddSort(p[i]);//调用公有函数AddSort()

}

}

voiddel(AddressList&addrlist)//删除记录

{

Node*p;

p=addrlist.GetHeadPtr();//调用GetHeadPtr()函数,获取首指针

if(p==0)//当链表中没有数据时

cout<<"无数据!

"<

else

{

char*n;

n=newchar;

ints;

cout<<"请输入要删除的记录的个数"<

cin>>s;//输入需要删除的数据个数

for(inti=0;i

{

cout<<"请输入要删除的姓名"<

cin>>n;//输入要删除的数据的姓名

addrlist.Delete(n);//调用公有函数删除记录

}

}//删除多条记录

}

voidshowall(AddressList&addrlist)//显示所有记录

{Node*p;

p=addrlist.GetHeadPtr();//调用GetHeadPtr()函数,获取首指针

if(p==0)

cout<<"无数据!

"<

else

addrlist.ShowAll();//调用公有成员函数,

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 考试认证 > IT认证

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1