C++简单通讯录管理课程设计南航.docx
《C++简单通讯录管理课程设计南航.docx》由会员分享,可在线阅读,更多相关《C++简单通讯录管理课程设计南航.docx(21页珍藏版)》请在冰豆网上搜索。
![C++简单通讯录管理课程设计南航.docx](https://file1.bdocx.com/fileroot1/2023-1/3/9ad9edbc-c4e5-48cc-b6c8-1831b2f08f0b/9ad9edbc-c4e5-48cc-b6c8-1831b2f08f0b1.gif)
C++简单通讯录管理课程设计南航
南京航空航天大学
《C++语言程序设计》课程设计
实验报告
班级:
学号:
姓名:
成绩:
指导老师:
日期:
年月日
一、程序功能
二、对题目的分析
三、设计中遇到的主要问题及解决方法
四、对设计的感想和心得
五、源程序
一、程序功能
本程序的功能是为用户提供简单的通讯录进行管理,通过该程序存储联系人信息,提供关键字查找功能,可以对数据进行修改、删除、添加等操作。
各按钮的功能如下:
查找记录:
以姓名为关键字,查找并显示该记录。
若查找不到,则显示“好象没有”;
添加记录:
将当前记录按姓名序加入通讯录,然后显示第一条记录;
第一条记录:
将当前记录指针移动至首节点,若已为首节点,则不移动;
前一条记录:
将当前记录指针向前移动一个节点,若已为首节点,则不移动;
后一条记录:
将当前记录指针向后移动一个节点,若已为尾节点,则不移动;
最后一条记录:
将当前记录指针移动至尾节点,若已为尾节点,则不移动;
加载:
从文件中入已保存的通讯录数据;
保存:
保存通讯录数据;
退出:
退出系统;
二、对题目的分析
本课程设计的数据有每个人的姓名,电话号码和Email地址等信息,并且所有人的数据以姓名为关键字按升序排放,存在前后关系,同时为了减少执行“添加”、“删除”等操作时对数据的过于复杂和繁琐的操作,采用双向链表而非数组来进行数据的的存储和操作。
同时需要一个文本文件来存储联系人信息,运行程序是从该文本文件中导入数据。
三、设计中遇到的主要问题及解决方法
1、从文本中写入数据时可能指针指错位置,导致不能正常进行。
解决的办法是对指针进行必要跟踪,把该函数写入独立的cpp文件中,单个进行检查。
2、从文本文件中载入数据时,当记录数为1的时,出现内存不能读的情况,当记录数为0时,当前记录数和总记录数以及用户信息显示的情况比较特殊,解决的办法是分三种情况,写段程序分别进行处理。
3、在运用链表编写程序的时候,很多地方不会做,解决的方法是多多咨询老师,与同学进行交流,多看例题,解决问题。
四、对设计的感想和心得
通过此次课程设计,是自己第一次将C++所学的内容用到实际课题中,虽然在编写函数时遇到了很大的困难,这主要是因为自己平时不下功夫,主要概念理解不清,但还是通过查阅资料、咨询老师及与同学进行交流的方式将其解决了。
对指针和链表的运用,还是不怎么熟练,经常出错,但设计完课程后,明白世上无难事,只要肯攀登,相信再经过一定的复习和练习,一定能通过期末考核。
五、源程序
#include
#include
#include
#include
#include
classNode
{
charName[10];//姓名
intOfficePhone;//办公室电话
intHomePhone;//住宅电话
charMobilePhone[15];//手机号码
charEmail[20];//email地址
Node*Next;//下一结点指针
public:
Node(char*name=NULL,intop=0,inthp=0,char*mp=NULL,char*email=NULL,Node*next=NULL)
{
if(name)strcpy(Name,name);
elsestrcpy(Name,"");
OfficePhone=op;
HomePhone=hp;
if(mp)strcpy(MobilePhone,mp);
elsestrcpy(MobilePhone,"");
if(email)strcpy(Email,email);
elsestrcpy(Email,"");
}
voidShow()//显示结点数据
{
cout<}
voidSetName(char*name)//修改姓名
{strcpy(Name,name);}
voidSetOfficePhone(intop)//修改办公室电话
{OfficePhone=op;}
voidSetHomePhone(inthp)//修改住宅电话
{HomePhone=hp;}
voidSetMobilePhone(char*mp)//修改手机号码
{strcpy(MobilePhone,mp);}
voidSetEMail(char*email)//修改email地址
{strcpy(Email,email);}
friendclassAddrList;//将AddrList类说明为友元类
friendvoidaddfromtxtfile(AddrList&);//将addfromtxtfile说明为友元函数
friendvoidwritetotxtfile(AddrList&);//将writetotxtfile说明为友元函数
};
//链表类
classAddrList
{
Node*HeadPtr;//链表首指针
Node*TailPtr;//链表尾指针
intTag;//排序状态标志,当Tag=1时,按姓名排序当Tag=2时,按办公室电话排序
public:
//成员函数
AddrList(Node*head=NULL,Node*tail=NULL,inttag=1)//构造函数,产生空链表,将tag的值置为1
{
HeadPtr=head;
TailPtr=tail;
Tag=tag;
}
voidAddTail(Node*p)//将p指向的结点加入到链表尾部
{
if(HeadPtr==NULL)
{
HeadPtr=p;
TailPtr=p;
p->Next=NULL;
}
else
{
TailPtr->Next=p;
p->Next=NULL;
TailPtr=p;
}
}
voidAddSort(Node*p)//将p指向的结点按Tag指定的顺序插入到链表中
{
Node*p1,*p2;
if(Tag==1)//按姓名排序
{
if(HeadPtr==NULL)//如果插入前原始链表为空链表
{
HeadPtr=p;
TailPtr=p;
p->Next=NULL;
}
else
{
if(strcmp(p->Name,HeadPtr->Name)<=0)//插在链表首部
{
p->Next=HeadPtr;
HeadPtr=p;
}
else//插在链表中间或尾部
{
p1=HeadPtr;
p2=HeadPtr;
while(p2->Next&&(strcmp(p2->Name,p->Name)<0))//查找待插入位置
{p1=p2;p2=p2->Next;}
if(strcmp(p2->Name,p->Name)<0)//插在链表尾部
{p2->Next=p;p->Next=NULL;TailPtr=p;}
else//插在链表中间,p2之前
{p->Next=p2;p1->Next=p;}
}
}
}
else//按办公室电话排序
{
if(HeadPtr==NULL)//如果插入前原始链表为空链表
{
HeadPtr=p;
TailPtr=p;
p->Next=NULL;
}
else
{
if((p->OfficePhone-HeadPtr->OfficePhone)<=0)//插在链表首部
{
p->Next=HeadPtr;
HeadPtr=p;
}
else//插在链表中间或尾部
{
p1=HeadPtr;
p2=HeadPtr;
while(p2->Next&&((p2->OfficePhone-p->OfficePhone)<0))//查找待插入位置
{p1=p2;p2=p2->Next;}
if((p2->OfficePhone-p->OfficePhone)<0)//插在链表尾部
{p2->Next=p;p->Next=NULL;TailPtr=p;}
else//插在链表中间,p2之前
{p->Next=p2;p1->Next=p;}
}
}
}
}
Node*LookUp(char*name)//按姓名查找结点,返回该结点指针
{
Node*p;
p=HeadPtr;
while(p!
=NULL)
{
if(strcmp(p->Name,name)==0)returnp;
p=p->Next;
}
returnNULL;
}
voiddel(char*name)//删除指定姓名的结点
{
Node*p1,*p2;
if(strcmp(HeadPtr->Name,name)==0)//若待删除的结点为首结点
{
p1=HeadPtr;
HeadPtr=HeadPtr->Next;
deletep1;
cout<<"删除了联系人"<system("pause");
}
else//删除其他结点
{
p1=HeadPtr;
p2=HeadPtr;
while(strcmp(p2->Name,name)!
=0&&p2->Next!
=NULL)
{
p1=p2;
p2=p2->Next;
}
if(strcmp(p2->Name,name)==0)
{
p1->Next=p2->Next;
deletep2;
cout<<"删除了一个联系人的信息!
"<system("pause");
}
}
}
voidSort(inttag)//按tag指定的关键字重新排序
{
Node*p1,*p2;
Tag=tag;
p2=HeadPtr;
HeadPtr=NULL;
TailPtr=NULL;
while(p2)
{
p1=p2->Next;
AddSort(p2);
p2=p1;
}
TailPtr->Next=NULL;
}
voidShowAll()//显示全部结点,每10个显示一屏
{
intn=0;
Node*p;
if(HeadPtr==NULL)
{
cout<<"链表为空,没有记录可显示!
"<}
elsefor(p=HeadPtr;p!
=NULL;p=p->Next)
{
p->Show();
n++;
if(n%10==0){cout<<"按任意键显示下一屏:
"<}
}
voidSetTag(intt)//置Tag值
{Tag=t;}
intGetTag()//取tag值
{returnTag;}
Node*GetHeadPtr()//取首指针
{returnHeadPtr;}
~AddrList()//释放链表空间
{
Node*p;
if(HeadPtr==NULL);
else
{
while(HeadPtr)
{
p=HeadPtr;
HeadPtr=HeadPtr->Next;
deletep;
}
}
}
voidCreateList(char*filename)//从二进制文件中读入数据,//构造链表
{
ifstreaminfile(filename,ios:
:
in|ios:
:
binary|ios:
:
nocreate);
if(!
infile){cout<<"文件"<else
{
infile.read((char*)&Tag,4);//读出二进制文件的第1个数据Tag
intn;
infile.read((char*)&n,4);//读出记录数
Node*p;
for(inti=0;i{
p=newNode;
infile.read((char*)p,sizeof(Node));
AddTail(p);
}
}
infile.close();
cout<<"数据从二进制文件加载成功!
"<}
voidWriteToFile(char*filename)//将链表中数据写入指定的二进制文件
{
ofstreamoutfile;
outfile.open(filename,ios:
:
out|ios:
:
binary);
outfile.write((char*)&Tag,4);
Node*p,*p1;
intn=0;
for(p1=HeadPtr;p1!
=NULL;p1=p1->Next)n++;
outfile.write((char*)&n,4);
p=HeadPtr;
while(p)
{
outfile.write((char*)p,sizeof(Node));
p=p->Next;
}
cout<<"成功导出二进制文件"<outfile.close();
}
};
voidDisplayMenu()//主菜单
{
char*menu[]={
"",
"",
"",
"",
"***********通讯录管理系统*************",
"",
"1.AddRecord",
"2.DeleteRecord",
"3.DisplayAllRecord",
"4.QuerybyName",
"5.ModifyRecord",
"6.AddfromaTextFile",
"7.WritetoaTextFile",
"8.Sort",
"9.Quit",
"请选择(1--9):
",
"",
"**************************************",
NULL};
for(inti=0;menu[i];i++)
cout<