C++语言课程设计报告一、课设名称:简单通讯录管理二、报告内容一、程序功能;二、课题分析;三、设计中遇到的问题与解决方法;四、对设计的感想和心得。五、源程序代码(含注释);六、典型测试数据组;(一)程序功能本程序的功能是为用户提供简单的通讯录进行管理,通过该程序存储联系人信息,提供关键字(只能是英文关键字进行查找)查找功能,可以对数据进行修改、删除、添加等操作。各按钮的功能如下:1增加记录:内部要按照当前排序标志插入结点,插入结点后,链表仍然保持有序;2删除记录:以姓名为关键字,查找并显示该记录,让用户确认是否要删除;3显示所有记录:按顺序显示所有记录,每屏显示十条记录,暂停,用户按Enter键继续;4查找记录:按姓名查找并显示一条记录,输入姓名后,显示该姓名下的所有信息;5修改记录:以姓名为关键字,查找并修改该记录,修改时用户按子菜单提示,指定修改哪一个数据项。如果修改的是当前排序字段,应重新排序;6从正文文件中添加数据到库表中:用户事先建立一个正文文件,存放待加入的数据,然后从该文件中一次性导入多个人的数据。7将库表的数据写入正文文件:将库表中的数据写入一个文本文件中。程序运行时,用户需输入文本文件的文件名;8排序库表:首先按照当前默认排序关键字排序,然后提示是否修改排序方式。改变排序方式的意义是在两种排序方式之间切换;9退出系统:退出系统,内部做结尾工作。(二)课题分析本课程设计的数据有每个人的姓名,办公室电话,住宅电话,手机号码和Email地址等信息,并且所有人的数据采用了以姓名为关键字的默认形式按升序排放,存在前后关系,同时也采用了以办公室电话为关键字进行排序,两者之间可以互相切换。为了减少执行“添加”、“删除”等操作时对数据的过于复杂和繁琐的操作,采用双向链表而非数组来进行数据的的存储和操作。同时需要一个文本文件来存储联系人信息,运行程序是从该文本文件中导入数据。(三)设计中遇到的问题及解决办法1程序运行时,排序方面总是出错,一运行到排序那里就会终止程序。经过上网搜索和学长,同学的帮助,重新分配了空间并编写了排序链表,终于得以正常运行。2在定义使用指针变量时混淆各个指针及其作用,未理解指针的各种定义。重新仔细复习了第九章的内容,并通过查找资料和模仿习题,得以正确编写完毕。3在运行时程序没有报错,但是运行后不能正常返回主菜单,而直接进入下一个功能。在经过自己的检查之后发现了在菜单栏中有个case没有加break这一问题,并解决。4在菜单中刚开始没有运用清屏,使得调试的时候屏幕上显示太多的内容,杂乱无章。后来在一些函数前添加system(‘cls’)后程序运行起来更加清楚。(四)对设计的感想和心得由于初次设计比较大的程序,没有任何实践经验,因此在设计中碰到了很多困难。在一开始我完全不知从何下手,后来我便在网上查询了一些资料,并结合书上及习题中的原型,尝试性地做了第三个程序。在做的过程中也碰到了些难题,但最后的成功给了我极大的鼓励。因此,我又尝试了第一个程序。由于是刚学的新内容,再加上时间紧迫,难度较大,举步维艰,在和同学的不断交流学习中终于完成了此次课程设计。通过这次课程设计,我学会了很多c++程序设计方面的知识,特别是关于链表指针的运用以及继承和派生,使我深有体会。这次课程设计不仅增强了自己的C++编程能力,同时增加了自己对于面向对象程序设计的深一层次的理解,又对书上的知识有了更好的巩固,将学到的知识运用到了实践中,使我受益匪浅。由于初学者水平有限,不足之处请老师海涵。(五)源程序代码(含注释)#includeiostream.h//数据流输入/输出#includefstream.h//文件输入/输出#includestdlib.h//定义杂项函数及内存分配函数#includestring.h//字符串处理#includeiomanip.h//参数化输入/输出#includectype.h//字符处理voidShowModiMenu(){char*submenu[]={(1)修改姓名,//修改姓名(2)修改办公室电话,//修改办公室电话(3)修改住宅电话,//修改住宅电话(4)修改手机号码,//修改手机号码(5)修改邮件地址,//修改email地址(0)不做任何修改!,//不作任何修改NULL};coutendl;for(inti=0;submenu[i];i++)coutsubmenu[i]endl;cout请输入选择:;}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*t=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,);next=t;}voidShow();//显示结点数据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说明为友元函数friendvoiddeleteall(AddrList&);//将deleteall说明为友元函数};voidNode::Show(){coutsetw(10)Namesetw(11)OfficePhone(O)setw(11)HomePhone(H)setw(14)MobilePhone(M)setw(20)EMailendl;}classAddrList{Node*HeadPtr;//链表首指针Node*TailPtr;//链表尾指针intTag;//排序状态标志,当tag=1,表示按姓名排序;默认按姓名排序.public://当tag=2,表示按办公室电话排序;AddrList(Node*,Node*,int);//构造函数,创建空链表,将tag的值置为1voidAddTail(Node*p);//将p指向的结点加入到链表尾部voidAddSort(Node*p);//将p指向的结点按Tag指定的顺序插入到链表中Node*LookUp(char*name);//按姓名查找结点,返回该结点指针voidDelete(char*name);//删除指定姓名的结点voidSort(inttag);//按tag指定的关键字重新排序voidShowAll();//显示全部结点,每10个显示一屏voidSetTag(intt);//置tag值intGetTag();//取tag值Node*GetHeadPtr();//取首地址~AddrList();//释放链表空间voidCreateList(char*filename);//从文本文件中读入数据,构造链表voidWriteToFile(char*filename);//将链表中数据写入指定的文本文件};AddrList::AddrList(Node*head=NULL,Node*tail=NULL,intt=1)//构造函数,创建空链表,将tag的值置为1{HeadPtr=head;TailPtr=tail;Tag=t;}voidAddrList::AddTail(Node*p)//将p指向的结点加入到链表尾部{if(HeadPtr==NULL){HeadPtr=p;TailPtr=p;p-next=NULL;}else{TailPtr-next=p;p-next=NULL;TailPtr=p;}}voidAddrList::AddSort(Node*p)//将p指向的结点按Tag指定的顺序插入到链表中{Node*p1,*p2;if(Tag==1)//以姓名顺序插入{if(HeadPtr==NULL)//链表为空{HeadPtr=p;TailPtr=p;p-next=NULL;}else{if(strcmp(HeadPtr-Name,p-Name)==1)//p插在链表首部{p-next=HeadPtr;HeadPtr=p;}else{p2=p1=HeadPtr;while(p2-next&&(strcmp(p-Name,p2-Name)==1))//p2不是尾结点{p1=p2;p2=p2-next;}//p1在p2前,同时向后移动if(strcmp(p-Name,p2-Name)==1){p2-next=p;p-next=NULL;TailPtr=p;}//p插在尾结点else{p-next=p2;p1-next=p;}//插在p1和p2之间}}}else//以办公室电话号码排序{if(HeadPtr==NULL)//链表为空{HeadPtr=p;TailPtr=p;p-next=NULL;}else{if(HeadPtr-OfficePhonep-OfficePhone)//p插在链表首部{p-next=HeadPtr;HeadPtr=p;}else{p2=p1=HeadPtr;while(p2-next&&(p-OfficePhonep2-OfficePhone))//p2不是尾结点{p1=p2;p2=p2-next;}//p1在p2前,同时向后移动if(p-OfficePhonep2-OfficePhone){p2-next=p;p-next=NULL;TailPtr=p;}//未扫描到,则p插在尾结点else{p-next=p2;p1-next=p;}//插在p1和p2之间}}}}Node*AddrList::LookUp(char*name)//按姓名查找结点,返回该结点指针{Node*p;p=HeadPtr;while(p!=NULL){if(strcmp(p-Name,name)==0)returnp;//p地址的姓名与所查找的相同p=p-next;}returnNULL;}voidAddrList::Delete(char*name)//删除指定姓名的结点{Node*p1,*p2;if(HeadPtr==NULL){cout链表为空,无信息可删!\n;}if(strcmp(HeadPtr-Name,name)==0)//p地址的姓名与所要删除的相同{p1=HeadPtr;HeadPtr=HeadPtr-next;deletep1;cerr删除了一个人的信息!\n;system(pause);}else{p1=HeadPtr;p2=HeadPtr-ne