




已阅读5页,还剩17页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
计算机科学与技术学院实践教学(实验、课程设计、实习)报告课程名称 C+语言程序设计 (课程设计) 设计选题: 电话簿管理系统 指导老师: 专业班级: 姓 名: 学 号: 完成日期: 指导教师评语:审查结论 签名: 年 月 日一、课题:电话簿管理系统这是一个简单的模拟手机的通讯录管理系统,该通讯录能够实现的查询内容有四项,分别是1.姓名2.电话3.与本人的关系4.所在单位或住址,这些属性都保存在一个结构中,而所有的操作都包含在一个record类中,使用运算符重载简化操作并且使用该系统能够实现如下功能:1.能够让用户输入原始记录,并将其保存在一个文件中以备往后查询等其他操作,并且在每次运行系统时可以读入保存在文件中的记录以进行各种操作。2.能够实现查询功能,其中查询方式又分为三种,分别是普通查询,按姓名查询和按关系查询。其中普通查询就是直接显示所有的记录,让用户浏览所有内容以得到其想要的电话号码等其他信息,此查询方式与手机的电话本相仿;按姓名查询,用户选择查询功能后可以在子菜单中选择按姓名查询,即用户只需要输入想要查找的人姓名就可以浏览所查找人的所有信息,同样,如果是选择按关系查找,输入其与本人的关系,就可以显示所有与本人处于此种关系的人的记录,此功能也与手机电话本中的分类查找相似。3.能够随时增加新的记录,并将其保存在已有的文件中。4.能够修改某条记录,如想要修改某人的记录,可以输入此人名字,然后桌面会显示此条记录,并提示您输入新的记录,选择保存操作,则修改完成。5.可以删除某条记录,并且保存删除后的记录而不影响其他操作。以上功能的实现主要遵循了一下设计要求:1. 使用链表实现数据的插入,删除,等操作2. 将输入链表中的记录用一个文件保存,并且能够将文件中的记录读入内存中并生成链表以供操作3. 用一个结构描述某记录的所有属性,用一个类包含 所有的操作函数,并且将结构作为类的私有成员4. 按如下格式输出所有记录:姓名 电话 关系 单位5. 使用菜单操作6. 要求对“”运算符实现重载。7. 设计如下函数原型以满足所有操作,并将这些函数作为类的公有成员record *set(record *); void show(record *); record *modify(record *); record *cancel(record *); void save(record *); record *load(record *); void search(record *);void handle_menu(record *);friend ostream &operator(istream &is,record &ob);其中int menu()函数要作为私有成员函数。;二、设计功能、算法、体会:该程序所有功能概述:.能够让用户输入原始记录,并将其保存在一个文件中以备往后查询等其他操作,并且在每次运行系统时可以读入保存在文件中的记录以进行各种操作。能够实现查询功能,其中查询方式又分为三种,分别是普通查询,按姓名查询和按关系查询。其中普通查询就是直接显示所有的记录,让用户浏览所有内容以得到其想要的电话号码等其他信息,此查询方式与手机的电话本相仿;按姓名查询,用户选择查询功能后可以在子菜单中选择按姓名查询,即用户只需要输入想要查找的人姓名就可以浏览所查找人的所有信息,同样,如果是选择按关系查找,输入其与本人的关系,就可以显示所有与本人处于此种关系的人的记录,此功能也与手机电话本中的分类查找相似。能够随时增加新的记录,并将其保存在已有的文件中。能够修改某条记录,如想要修改某人的记录,可以输入此人名字,然后桌面会显示此条记录,并提示您输入新的记录,选择保存操作,则修改完成。 可以删除某条记录,并且保存删除后的记录而不影响其他操作。1. 头文件部分:基本思想:首先有一个宏定义1. #define ASK(p) do 2. p=new record;3. if(p=NULL) coutmemory fail!endl;exit(-1); 4. while(0)用于以后分配内存方便。然后定义了一个struct rec 结构,用来存储记录的四项内容,这样便于对记录内容的操作,然后定义了一个record类的声明,其私有成员包括一个结构体的对象,一个指向对象自己的指针*next,起作用主要是用在用类的对象构造链表时使其指向下一个节点,然后还有一个menu()函数,该函数是显示的主菜单画面,这样将以上几项作为私有成员就能保证数据的安全性了。 然后是公有成员了,其首先包括了一个构造函数和一个析构函数,构造函数主要用来对室友成员初始化赋值,由于定义的struct成员都是字符数组,所以初始化时都赋值为0。析构函数用来释放内存空间。然后定义了一个静态变量count作为类的公有成员,目的是记录链表的节点数或者说是文件的记录数,最后就是包含了所有的将会使用到的函数的声明。 具体步骤:建立如下函数声明:record *set(record *); 用于输入原始数据,或者临时增加记录,返回值是累的指针,参数同样是类的指针象top,这样做是应为该函数是对类的对象进行的操作。 void show(record *); 用于显示所有的记录,由于其不会对文件内容进行更新操作,所以不需要返回值,参数是类的指针toprecord *modify(record *); 用于修改记录,由于对记录进行了更新操作,故要有返回值,返回值是和参数都是类的指针record *cancel(record *); 用于删除记录,返回值和参数都是类的指针void save(record *); 用于保存记录于指定的文件record.dat中,无返回值,参数为类的指针toprecord *load(record *); 用于从指定文件record.dat中读取记录至内存中,并生成链表,返回值和参数都是类的指针topvoid search(record *); 查询函数,用于查询与输入的字符相匹配的记录并显示出来,无返回值,参数为类的指针void handle_menu(record *); 菜单控制函数,当用户按照操作输入相应的字符后,该函数就会调用相应的函数以实现相应的操作,无返回值,参数是类的指针topfriend ostream &operator(istream &is,record &ob);这是两个运算符的友元重载,其中operator要能够实现多个数据的输入,并且要允许输入有空格的字符。其声明格式如下:5. record *set(record *); 6. void show(record *); 7. record *modify(record *); 8. record *cancel(record *); 9. void save(record *); 10. record *load(record *); 11. void search(record *);12. void handle_menu(record *);13. friend ostream &operator(istream &is,record &ob);体会: 一个条理清晰的头文件对一个程序的设计是非常重要的,所以头文件的建立一定要格式清晰,明朗,让人一看就知道改程序有哪些函数,哪些功能。另外,在这里我体会到了宏定义的好处,适当的使用宏定义可以明显的提高代码的编写效率,所以在本程序中,我使用了一个宏定义用来分配内存地址,这样就省去了很多需要重复使用相同代码的麻烦。set()函数:功能:用于输入原始数据,或者临时增加记录,返回值是累的指针,参数同样是类的指针象基本思想:该函数是用来输入或增加记录的,算法比较简单,主要就是使用一个for循环,循环的输入想要插入或增加的记录,并将记录保存。具体步骤: 函数开始,使用一个if语句,用来判断top-count是否为零,若为零,说明内存中没有记录,于是调用load()函数读入记录,若文件中也没有记录则显示没有记录,若文件中有记录则读入内存生成链表,然后定义两个类的指针old和star,并且给star分配一个内存地址,将top链表的首地址赋给old,使用一个while语句让old指向其下一个节点,然后输入记录,且在输入记录之前输入将要输入的记录数,并将其赋给M,执行for(int i=0;iM;i+)循环用以生成M个节点保存记录,在for循环中每执行一次count数都加一,语句如下所示:15. for(int i=0;icount; 20. coutt姓名:);21. if(strcmp(,0)=0)22. break;23. 24. coutt电话:star-rc.tele;25. coutt关系:star-rc.relat;26. coutt单位:star-rc.unit;27. coutcount=1) top=star; 30. old-next=star;31. old=star;32. ASK(star);33. ;每次循环都调用ASK给star分配新的节点。输入的记录都保存在临时指针star里,且将star的头节点赋给top用于返回,将old-next指向star,old=star目的是使old到达链表的最后一个节点,当跳出循环后使old-next=NULL以结束链表。最后返回top,这样top就指向了新生成的链表的头结点。体会:链表在动态存储上确实要比数组优越很多,而且操作要比数组方便的的多,也易于管理,还有就是在分配内存空间时使用了之前的一个宏定义,这使的代码的编写简单了很多。 查询功能:功能:该函数主要用来实现查询功能,其中查询方式又分为三种,分别是普通查询,按姓名查询和按关系查询。算法思想:当选择查询选项后,会有一个查询界面菜单出现,会现实3种不同的查询方式,这里主要用一个switch语句就可以实现,然后根据输入的数字调用相应的函数。 普通查询就是直接调用显示函数显示所有的记录,让用户浏览所有内容以得到其想要的电话号码等其他信息,;按姓名查询和按关系查询,即用户只需要输入想要查找的人姓名或关系,此处使用一个strcmp函数,用来检查匹配字符,如果字符匹配则现实相应的记录。具体步骤:首先设定两个字符数组,一个用来存放输入的选择数字,一个用来存放输入的查找内容。然后函数会 显示一个菜单界面提示用户输入相应的选择。接着有一个语句用来判断用户的选择,语句如下:34. gets(choose);35. while(1)36. 37. cn=atoi(choose);38. if(cn !=1& cn !=2&cn!=3)39. 40. coutt输入错误,重选1-3:)=0)|(cn=2& strcmp(input,p-rc.relat)=0)49. 50. 51. coutt找到信息如下:endl;52. coutt名字t号码t关系t单位n;53. trc.teletrc.relattrc.unitnext;55. 56. else57. 58. p=p-next;59. 60.61.62. while(p!=NULL);若没有找到相应的记录,则显示没有找到相应记录,同时返回。体会:灵活运用if语句可以简化函数代码,如本程序中的if(cn=1&strcmp(input,)=0)|(cn=2& strcmp(input,p-rc.relat)=0),将所有的判断条件写在一个语句中,大大简化了代码。另外就是要注意循环语句的循环条件,以及其开始和结束的地方,这是一个难点,往后还要多加注意。4.菜单控制函数功能:主要用来显示程序的主界面算法思想:这是一个很简单的函数,基本上就是一个switch语句就可以了,根据用户输入的数字调用相应的函数。主要步骤:进入函数,使用一个for(;)的无限次循环,在该循环中使用一个switch(menu()语句,其中menu()是显示菜单函数,其返回值是用户输入的选择功能的相对应的数字,下面是个数字对应的功能:输入记录显示所有记录查找记录删除记录修改记录保存文件读入文件退出其调用语句及相应函数如下函数63. case 0:top=set(top); break; /*输入记录*/64. case 1:show(top);break; /*显示全部记录*/65. case 2:search(top);break; /*查找记录*/66. case 3:top=cancel(top);break; /*删除记录*/67. case 4:modify(top);break; /*修改纪录*/68. case 5:save(top);break; /*保存文件*/69. case 6:top=load(top); break; /*读文件*/ 70. case 7:exit(0);break;该函数会根据用户输入的数字或字符调用相应的函数。该函数设立了一个字符数组用来接收用户输入的字符,目的是可以将用户输入的非数字字符转换成相应的数字,当然,如果用户输入的数字不在17之间则会显示“输入的数字不正确,请您输入正确的数字”,用户这时可以再次输入 。体会:唯一的感觉就是switch语句是一个很好用的语句啊,而且是一个很有用的语句,几乎在所有的需要用到菜单的程序中都会使用到,并且配合for循环语句,就是很好的控制菜单函数。读取函数:功能:主要用来将硬盘中的文件记录读取到内存中,并生成链表以供函数操作。算法思想:首先建立一个输入流类in,使用in.open(record.dat,ios:in|ios:nocreate);打开文件,并使用if语句判断是否正常打开文件。如果不能正常打开文件,则显示文件不存在。正常打开文件后,首先将记录个数读入并赋给top-count,然后建立类record的两个指针*p和*old,并且现将top的头结点赋给p,使用一个for语句读入top-count条记录。For语句中主要有以下方法,将读入的记录存入节点p,然后在使用ASK(p-next)为p分配新的内存,并将p赋给old,然后p=p-next使P指向下一结点,如此循环。直到读完文件中的记录,实施代码如下:71. ifstream in;72. in.open(record.dat,ios:in|ios:nocreate);73. if(!in)74. 75. coutt文件不存在!请输入数据建立新文件endl; 76. return top;77. 78. coutnt取文件top-count; 81. in.ignore(); 82. record *p=top; 83. record *old;84. for(int i=0;icount;i+)85. 86. in*p; 87. ASK(p-next); 88. old=p; 89. p=p-next; 90. in.ignore();91. 最后使old-=NULL;结束链表;然后关闭文件,显示读入的记录数,最后返回top体会:其实在最初我是选用的数组来存储文件记录,但是后来发现一个问题,那就是用数组存储的记录,在读取记录到内存中的时候不能够对这些记录进行按条操作,当然这也可能是我没找到好的方法,但不管怎么样我都觉得很麻烦,想了很多办法都没能实现,最后只好下决心改用链表动态存储文件记录,这样终于实现了文件的读取功能,并且能够对读取的记录进行任何操作。由此可见动态存储的优越性啊。再有就是以后写程序的时候一定要事先各方面都考虑到,不要到了最后才发现程序设计的不合理以至于要从头来过,这样就很耽误时间。三. 函数结构图以下结构图展示的本程序包含的所有函数及各个函数的从属关系:Menu()Cancel()Hand_menu()Load()Save()Set()Modify()Main()Search()Show()Operator()Operator()图1:程序的函数结构四、系统运行:1.程序运行后的第一个界面 *菜单* * 0. 输入记录: * * 1. 显示所有记录: * * 2. 查找记录: * * 3. 删除记录: * * 4. 修改记录: * * 5. 保存文件: * * 6. 读入文件: * * 7. 退出: * * 请输入您的选择(07):2.这是输入记录显示的界面 请输入您的选择(07):0 请稍候,取已有文件. 取文件 取入3条记录。 输入数据:输入记录条数:5 姓名:龚勇 电话:629313 关系:本人 单位:12舍313 姓名:陈洲 电话:123456 关系:室友 单位:12舍313 姓名:文际琼 电话:464654 关系:大学同学 单位:11舍 姓名:杨贝 电话:899746 关系:大学同学 单位:11舍 姓名:李娇 电话:999889 关系:大学同学 单位:11舍按任意键继续3.这是执行显示函数后的界面 * 请输入您的选择(07):1现在共有如下8条记录: 名字 电话 关系 单位 9 9 9 9 0 0 0 0 1 2 2 2 龚勇 629313 本人 12舍313 陈洲 123456 室友 12舍313 文际琼 464654 大学同学 11舍 杨贝 899746 大学同学 11舍 李娇 999889 大学同学 11舍按任意键继续在此只截取以上几个界面以供证明本程序确实能够正常运行,其他部分请用户自行运行查看。五、源程序:1头文件#if !defined(gongyong_h)1.#define gongyong_h2.#include3.#include4.#include 5.#include6.#include7.#include ctype.h8.#include conio.h9.10.#define ASK(p) do 11.p=new record;12.if(p=NULL) coutmemory fail!endl;exit(-1); 13.while(0)14.15.16./申请动态内存并判别是否申请成功17.18. /定义记录类19. struct rec20.21.char name20;22.char tele15;23.char relat10;24.char unit20;25. 26.;27.28.class record29.30.private:31. rec rc; /对象成员32. record *next; /指向自身的指针33. int menu();34. 35.public:36.record();37.record();38.static int count;39.40.41.record *set(record *); 42.43.void show(record *); 7.record *modify(record *); 48.49.record *cancel(record *); 50.51.void save(record *); 52.53.record *load(record *); 54.55.void search(record *);56.57.void handle_menu(record *);58.59.friend ostream &operator(istream &is,record &ob);61.62.;63.64.#endif65.66.67./控制菜单函数68.void record:handle_menu(record *top)69. /int x;70. for(;)71. 72. switch(menu() /*调用主菜单函数,返回值整数作开关语句的条件*/73. 74. case 0:top=set(top);75. 76. break;/*输入记录*/77.78. case 1:show(top);break; /*显示全部记录*/79.80. case 2:search(top);break; /*查找记录*/81.82. case 3:top=cancel(top);break; /*删除记录*/83.84. case 4:modify(top);break; /*修改纪录*/85.86. case 5:save(top);break; /*保存文件*/87.88. case 6:top=load(top); break; /*读文件*/ 89.90. case 7:exit(0);break;91. 92. default:cout对不起,请输入正确的数字!count=0)106
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 黄冈师范学院《动画设计与制作》2023-2024学年第二学期期末试卷
- 邢台应用技术职业学院《计算机通信与网络实验》2023-2024学年第二学期期末试卷
- 丽江文化旅游学院《冶金热力学参数测定与分析》2023-2024学年第二学期期末试卷
- 河南师范大学《无机非金属材料工艺学》2023-2024学年第二学期期末试卷
- 上海外国语大学贤达经济人文学院《网络传播与法规》2023-2024学年第二学期期末试卷
- 湖北工程学院《针织物设计与试织》2023-2024学年第二学期期末试卷
- 广东南方职业学院《环境工程CAD实验》2023-2024学年第二学期期末试卷
- 北京北大方正软件职业技术学院《建筑工程制图与识图》2023-2024学年第二学期期末试卷
- 重庆五一职业技术学院《图案与字体设计》2023-2024学年第二学期期末试卷
- 高职就业指导与创业教育
- 提高安全意识共建平安校园
- 2025安徽蚌埠市龙子湖区产业发展有限公司招聘22人笔试参考题库附带答案详解
- 华为笔试题目大全及答案
- 产业研究报告-中国水环境监测行业发展现状、市场规模及投资前景分析(智研咨询)
- 偿二代下我国财险公司偿付能力影响因素的深度剖析与实证研究
- 【嘉峪关】2025年甘肃嘉峪关市事业单位集中引进高层次和急需紧缺人才50人(含教育系统)笔试历年典型考题及考点剖析附带答案详解
- 全国防灾减灾日宣传课件
- 青少年学法知识讲座课件
- 2025阿里地区普兰县辅警考试试卷真题
- 青年纪律教育课件:共青团纪律条例解读与实践
- 清代文学教案
评论
0/150
提交评论