1、简单通讯录c 课程设计docC+课程设计简单通讯录管理0411204班041120431董力1程序菜单功能 通讯录是一个简单的数据库库表,每一个记录(结点)包含个人所有通讯信息。程序执行过程为:显示主菜单,用户在choice:处输入选项(按照功能列表输入19中的一个数字),按回车后执行相应的功能。 具体函数的功能请见下面4. 提供典型测试数据组2分析,感想。 (1)、数据结构 程序采用一个单向链表类结构实现,每个结点代表一个通讯记录,链表类实现通讯录多个记录的管理工作。 (2)、新增功能 可批量输入,一次输入多个人的信息。 (3)、遇到的问题 这次课设遇到的问题较多,首先就是学过的知识无法融会
2、贯通。在完成课设时,许多知识点需要翻书查找(比如在输入输出流的部分),有时需要请教他人。其次,是程序十分长,而且自己小错误不断,这样检查起来非常麻烦。所以当运行程序时,出现了102个错误,其中大部分不是算法的问题,而是像少了“;”或是if中判断是否相等时用“=”而不是“=”。最后,程序较长,编辑起来费力,有时一个算法出问题,其后的几个函数连带都会出问题,而且编译时没有显示有错误,这让检查起来非常麻烦,需要一遍又一遍阅读,有时还要请教别人一起阅读,耗时很长。 (4)、感想这次课设成功完成,让我非常惊讶。平时作业的一个程序,有时需要一个下午来完成。现在,我发现原来我也可以完成如此复杂的程序。更重要
3、的是,这次课设让我的一些知识能记得更加深刻,对于编程也更加熟练。而且,我知道请教他人的重要性, 有时自己一个人想不出来的问题,问问同学,可以更好更快的解决。最后,我知道了光把理论知识还不够,还要不断实践,这样才能将知识掌握得更加牢固,更加灵活。3提供有注释的源程序#include #include #include #include #include #include class Node char Name10; /姓名 int OfficePhone; /办公室电话 int HomePhone; /家庭电话 char MobilePhone15; /手机号码 char E_Mail20;
4、/电子邮箱地址 Node*Next; /下一个结点指针public: Node(char na=sb,int op=0,int hp=0,char mp=0,char em=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中 void S
5、how() /显示结点数据 couttNametOfficePhonetHomePhonetMobilePhonetE_Mailendl; /输出一个记录中的所有数据 void print(ofstream &out) /将结点数据写入文件 out.open(addresslist.text);/打开名为addresslist.text的文档 outtNametOfficePhonetHomePhonetMobilePhonetE_MailNext=p;/如果不为空,则尾指针的Next指向p TailPtr=p; /将p的值赋给TailPtr TailPtr-Next=NULL;/使TailP
6、tr的成员Next为空 void AddSort(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; /
7、如果p大,就将下一个数据赋给p1,否则跳出循环 if(strcmp(p-Name,p1-Name)Next=p1;/将p的下一个指向p1 if(HeadPtr=p1) HeadPtr=p;/如果首指针等于p1,则将p的值赋给首指针 else p2-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-OfficePhon
8、e)(p1-OfficePhone)&p1-Next!=NULL) p2=p1;p1=p1-Next; if(p-OfficePhone)OfficePhone) p-Next=p1; if(HeadPtr=p1) HeadPtr=p; else p2-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)HomePhone) p-Ne
9、xt=p1; if(HeadPtr=p1) HeadPtr=p; else p2-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)Next=p1; if(HeadPtr=p1) HeadPtr=p; else p2-Next=p; else p1-Next=p;
10、 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)Next=p1; if(HeadPtr=p1) HeadPtr=p; else p2-Next=p; else p1-Next=p; p-Next=NULL; Node *LookUp(char*name)/按姓名查找结点,返回该结点指针 Node *p=HeadPtr;/定义一个Node型指针
11、,初始值为HeadPtr while(p!=NULL)/当链表不为空时 if(strcmp(p-Name,name)=0)/循环比较数据中的Name成员 return p;/如果存在,返回结点 p=p-Next;/将p的下一组数据赋给p return NULL;/如果不存在,返回值为空 void Delete(char*name)/删除指定姓名的结点 Node *p1,*p2; if(HeadPtr=NULL)/当链表为空时 coutName,name)!=0& p1-Next!=NULL)/查找所在位置 p2=p1;/将p1的值赋给p2 p1=p1-Next;/p1指向下一条记录 if(st
12、rcmp(p1-Name,name)=0)/若找到该姓名对应的数据,删除该数据 if(p1=HeadPtr)/如果p1在第一条,则将首指针指向下一条记录,将p1空出 HeadPtr=p1-Next; else/否则将p1的上一个记录的成员Next直接指向p1的下一条记录 p2-Next=p1-Next; delete p1;/释放p1的空间 cout删除了一个数据!n; else /若找不到,则输出通讯录上没找到该条记录! coutnameNext;/将head的下一条数据赋给head delete p;/释放p的空间 void Sort(int tag) /按Tag指定的关键字重新排序 Ta
13、g=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重新按关键字排序 void ShowAll() /显示全部结点,每10个显示一屏 Node *p=HeadPtr;/定义一个Node型指针p,初始化为首指针的值 int i=1; /定义一个整
14、型变量,计算现实的数据个数 system(cls); /清屏 while(p) /当p不为空时,进行循环 coutiShow(); /循环输出数据p p=p-Next; /将下一条记录的值赋给p if(!(i+%10) /当i是10的倍数时,暂停程序并清屏 system(pause); system(cls); void SetTag(int t) /重置Tag的值 Tag=t; int GetTag() /获取Tag的值 return(Tag);/返回Tag的值 int Count() /计算链表中有多少个结点 Node*p;/定义一个Node型指针p int t=0;/定义一个整型变量t,
15、用来计算链表中结点的个数 p=HeadPtr;/将首指针的值赋给p while(p-Next!=NULL)/当链表不为空时 t=t+1;/每当数据不为空时,t就加1 p=p-Next;/p指向下一条记录 t=t+1; /因为当p-Next=NULL是就退出程序,所以末尾t要加1 return t;/返回t Node*GetHeadPtr()/获取链表首指针 return HeadPtr;/返回首指针 AddressList() /析构函数,释放链表空间 Node*p;/定义一个Node型的指针变量 while(HeadPtr!=NULL)/链表不为空,进行循环 p=HeadPtr;/将第一条数
16、据赋给p HeadPtr=HeadPtr-Next;/将下一条数据赋给首指针 delete p;/释放p的空间 #define Len sizeof(class Node)/定义常量Len为Node类数据的长度 void CreateList(char*filename)/从二进制文件中读入数据,构造链表 Node*p100;/定义一个有100个数据空间的指针数组 int i=0,j=0;/定义两个整型变量,来记录第几条数据和读取数据的个数 fstream file(filename,ios:in|ios:binary);/定义一个文件流对象 if(!filename)/当文件为空时,无法打开
17、 cout不能打开文件:filenameendl; exit(1); file.read(char*)&Tag,sizeof(int);/从文件中读取Tag file.read(char*)&j,sizeof(int);/从文件中读取数据的个数 p0=new Node; /申请一个p的动态存储空间 while(file.read(char*)pi,Len)!=0)/从文件中读取Len长度的数据不为0 pi+1=new Node; AddSort(pi+1);/调用公有成员函数AddSort(),将文件中数据读取后,重新排序 file.close;/关闭文件 void WriteToFile(c
18、har*filename)/将链表中的数据写入指定的二进制文件 Node*p;/定义一个Node型的指针变量 p=HeadPtr;/将首指针的值赋给p fstream file(filename,ios:in|ios:binary);/定义一个文件流对象 if(!filename)/当文件为空时,无法打开文件 cout不能打开文件:filenameNext; file.close;/关闭文件 void outtxt(char *file)/将数据从文件file导出 Node *p=HeadPtr;/定义一个Node型指针变量,初始值为HeadPtr int n=1;/定义一个整型变量,作为数据
19、的序号 fstream out(file,ios:out);/以写入的方式打开正文文件 if(!out)/定义一个输出文件流对象 cout不能打开该文件:fileendl; exit(1); while(p) outn+t(*p).Namet(*p).OfficePhonet(*p).HomePhonet(*p).MobilePhonet(*p).E_MailNext; out.close(); ;int menu_select() /菜单实现 char*a=1.Add Record,2.Delete Record,3.Display All Record,4.Query, 5.Modify
20、Record,6.Add from a Text File,7.Write to a Text File, 8.Sort,9.Delet All,0.Quit,NULL;/将菜单的选项赋给数组 int i,choice;/定义两个整型变量,一个用于输出选项,一个用于选择,并调用相关函数 do system(cls); coutnn=Address Book Managing Syetem=nn; for(i=0;ai;i+)/循环输出选项 coutaiendl; coutn=n; coutchoice;/输入choice while(choice9);/在0到9的菜单中做出选择 return(
21、choice);/返回所选的值void add(AddressList&addrlist) /增加记录 Node *p50;/一次需要输入的数据 char n100,m100,o100;/姓名,手机,电子邮箱 int q,r;/办公和家庭电话 int i,j; coutj; cout请依次输入姓名、办公电话、家庭电话、手机号码和电子邮箱地址:; for(i=0;inqrmo;/输入数据的各个成员 pi=new Node;/申请动态存储空间 pi-SetName(n);/调用公用成员函数,修改姓名 pi-SetOfficePhone(q);/调用公用成员函数,修改办公电话 pi-SetHomeP
22、hone(r);/调用公用成员函数,修改家庭电话 pi-SetMobilePhone(m);/调用公用成员函数,修改手机 pi-SetE_Mail(o);/调用公用成员函数,修改电子邮箱 addrlist.AddSort(pi);/调用公有函数AddSort() void del(AddressList&addrlist) /删除记录 Node *p; p=addrlist.GetHeadPtr();/调用GetHeadPtr()函数,获取首指针 if(p=0) /当链表中没有数据时 cout无数据!endl; else char*n; n=new char; int s; cout请输入要删除的记录的个数s;/输入需要删除的数据个数 for(int i=0;is;i+) cout请输入要删除的姓名n;/输入要删除的数据的姓名 addrlist.Delete(n);/调用公有函数删除记录 /删除多条记录void showall(AddressList&addrlist)/显示所有记录 Node *p; p=addrlist.GetHeadPtr();/调用GetHeadPtr()函数,获取首指针 if(p=0) cout无数据!endl; else addrlist.ShowAll();/调用公有成员函数,
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1