手机通讯录(结构体实现,链表还不会!)

来源:互联网 发布:淘宝店被占用了怎么办 编辑:程序博客网 时间:2024/04/28 02:32
//global.cppint num=0;//main.cpp#include<iostream>#include"add_list.h"using namespace std;int main(){linkman man[N];//linkman类型数组man,最多存15个人信息char na[N]={0};//存储每个人姓名第一个字母,这种赋值属于字符数组的赋值,区别去字符串的初始化int sign[N]={0};//存储联系人编号in_data(man,na);//读取数据,并获得联系人数目numcount i;for(i=0;i<num;i++)//给每个联系人一个编号sign[i]=i;in_turn(na,sign);//对联系人按姓名从小到大排序show_data(man,sign);//显示排序后的联系人show_function(man,na,sign);//功能界面}//add_list.hextern int num;struct linkman{char name[10];char tel_num[12];//以11位手机号为例说明char kind;//联系人分类变量char e_mail[30];//邮箱限制在30个字节};void in_data(linkman *p,char *q);#define N 40typedef int count;void show_data(linkman *p,int *q);//显示联系人函数void show_menu();//功能显示菜单void show_function(linkman *p,char *q,int *r);//功能实现函数void add_man(linkman *p,char *q,int *r);//添加联系人函数void out_data(linkman *p,char *q,int *r);//程序退出时将数据保存入文件void in_turn(char *p,int *q);//将姓名按字母排序,q数组则存放排序后的联系人编号int com_name(linkman *p,char *q);//比较输入姓名与已存姓名是否有相同的void edit_man(linkman *p);//修改联系人信息void del_man(linkman *p,char *q,int *r);//删除联系人void call(linkman *p);//add_list.cpp#include<iostream>#include<fstream>#include"add_list.h"using namespace std;void in_data(linkman *p,char *q){ifstream infile;infile.open("linkman.txt",ios::in);//只读方式打开,文件必须存在if(!infile.is_open()){cout<<"open error";exit(1);}count i=0;/***********************************************/char ch;//姓名前的第一个字母//***********规定:存入姓名的时候必须先存首字母,方便后续按姓名排序//***********这里要求先存的首字母应该是另外单独放个数组,只作为排序参考而不显示,文件中要存放if(!infile.get(ch))//读取EOF,函数返回值为0,执行if,退出程序{cout<<"文件为空!";//exit(1);//文件为空,不退出,回到功能界面}else{infile.seekg(0,ios::beg);//不是空文件,则将指针移动到文件头,开始读取while(!infile.eof())//在指向EOF时,还会执行一次,所以,最后一个联系人是空的,什么内容也没有,这个问题暂时先不管{infile>>q[i]>>p[i].name>>p[i].tel_num>>p[i].kind>>p[i].e_mail;//先将姓名第一个字符存入na数组i++;}num=i;//确定实际联系人数量,不用减一,因为这里读取字符串的情况不会多执行一次//show_data(p,q,r);//显示联系人数据//此时联系人还未进行编号,不能显示}infile.close();cout<<"当前文件中有"<<num<<"个联系人"<<endl;cout<<"数据读取完成"<<endl;}void show_data(linkman *p,int *q)//p指向联系人数组,q指向编号数组sign{count i;cout<<num<<endl;for(i=0;i<num;i++){cout<<"第"<<i<<"个联系人"<<endl;cout<<p[q[i]].name<<'\t'<<p[q[i]].tel_num<<'\t'<<p[q[i]].kind<<'\t'<<p[q[i]].e_mail<<'\n';}cout<<"联系人数据显示完成!"<<endl;}void show_menu(){cout<<'\t'<<"手机通讯录系统"<<'\t'<<endl;cout<<"1.添加联系人"<<'\t'<<"2.查看联系人"<<'\n';cout<<"3.拨打电话"<<'\t'<<"4.编辑联系人"<<'\n';cout<<"5.删除联系人"<<'\t'<<"6.退出"<<'\n';}void show_function(linkman *p,char *q,int *r){char i;//in_data(p,q);//读取文件数据放到主函数显示功能界面前while(1){show_menu();//显示功能菜单cin>>i;switch(i){case '1':add_man(p,q,r);break;//p这里多次传递地址,都是结构体数组首地址case '2':show_data(p,r);break;//显示联系人数据case '3':call(p);break;//拨打电话case '4':edit_man(p);break;//修改联系人数据,case '5':del_man(p,q,r);break;//删除联系人case '6':out_data(p,q,r);break;//退出前保存数据到文件}if(i=='6')break;//如果选择的是退出功能,则在保存数据后退出,否则循环继续}}void add_man(linkman *p,char *q,int *r){char ch[10];//存储新输入的姓名int n;cout<<num<<endl;cout<<"欢迎来到添加联系人界面:"<<endl;cout<<"姓名:";cin>>ch;//输入需要添加的姓名n=com_name(p,ch);//判断姓名是否已经存在if(n>=0&&n<num)//姓名存在{cout<<endl<<"此姓名已经存在"<<endl;return;//姓名存在,直接返回}else if(n==-1)//姓名不存在则执行以下的添加信息操作{strcpy(p[num].name,ch);//输入名字cout<<"姓名首字母:";cin>>q[num];//输入姓名首字母r[num]=num;//添加联系人的编号   //漏掉了这一句,由于之前初始化的时候,sign数组初值全部为零,也就是代表文本中第一个联系人,刘中华  //在没有给联系人标号时,排序自然跟他没关系,输出的时候也输出不到他,按我的程序输出的时候,人数是对的         //但是,只是多输出了第一个人而已cout<<endl;cout<<"手机号:";cin>>p[num].tel_num;cout<<endl;cout<<"类别:";cin>>p[num].kind;cout<<endl;cout<<"电子邮箱:";cin>>p[num].e_mail;cout<<endl<<"新增联系人成功";num+=1;in_turn(q,r);//添加联系人后排序,再显示show_data(p,r);cout<<"添加后的联系人数目"<<num<<endl;return;}}void out_data(linkman *p,char *q,int *r)//q指向na字符数组,r指向sign整型数组{ofstream outfile;//定义文件流对象outfile.open("linkman1.txt",ios::out);//以输出方式打开文件,只写操作,新建文件或清空文件内容(文件存在)count i;for(i=0;i<num;i++){outfile<<q[i]<<'\t'<<p[r[i]].name<<'\t'<<p[r[i]].tel_num<<'\t'<<p[r[i]].kind<<'\t'<<p[r[i]].e_mail;if(i!=num-1)outfile<<'\n';//最后一行不输出回车}cout<<"数据保存完成"<<endl;outfile.close();}/*********************************************************************************/*关于排序后数据的变化说明:排序后,变化的只是na数组,和sign数组中的内容,联系人数组还是/*原来的顺序,只是在显示的时候按照sign所存的编号顺序即可,文本中存的是什么顺序,内存中man/*数组的存放也是那个顺序,从i到num**********************************************************************************/void in_turn(char *p,int *q)//p对应na字符数组,q对应sign整型数组,按由小到大排序{count i,j,k;char ch;int mid; //中转变量for(i=0;i<num-1;i++)//趟数n-1{k=0;for(j=num-1;j>0;j--,k++)//每趟比较次数{if(p[k]>p[k+1]){ch=p[k];p[k]=p[k+1];p[k+1]=ch;//姓名首字母交换完成mid=q[k];q[k]=q[k+1];q[k+1]=mid;//联系人编号交换完成}}}}int com_name(linkman *p,char *q)//p指向man数组,q指向输入的姓名数组{int n=-1;count i;for(i=0;i<num;i++){n=strcmp(p[i].name,q);//字符串比较函数,可以按排序后的联系人顺序比较也可以直接比较,记住相同的联系人编号即可if(n==0){cout<<"此姓名已经存在"<<endl;//姓名存在,返回联系人的编号i,这个不影响数据的编辑修改,//只是显示的时候按照排序后的顺序显示即可return i;//姓名已经存在返回i到num的一个整数}}if(n!=0){cout<<"此姓名不存在"<<endl;return -1;//这里模仿文件指针位置,姓名不存在返回-1,}}void edit_man(linkman *p){cout<<"输入待编辑联系人姓名:";char ch[10];cin>>ch;int n;n=com_name(p,ch);//判断姓名是否存在,n则代表了联系人的标号,是第几个联系人if(n>=0&&n<num)//姓名存在{cout<<endl<<"此姓名存在"<<endl;cout<<"输入电话号码:";cin>>p[n].tel_num;cout<<endl<<"输入联系人类别:";cin>>p[n].kind;cout<<endl<<"输入电子邮箱:";cin>>p[n].e_mail;cout<<endl<<"信息修改完成"<<endl;}elsereturn;//姓名不存在直接返回}/******************************************************************/*删除应该有两种思路,一种,从要删除的文职开始,后面的依次往前覆盖,另一种/*用先输出,再读入的方式,这里用第一种的话,na数组的内容与man数组不对应,需要寻找,/*较麻烦,用第二种********************************************************************/void del_man(linkman *p,char *q,int *r)//q指向sign整型数组{count i;int n,k;ofstream outfile;outfile.open("linkman.txt",ios::out);if(!outfile.is_open()){cout<<"打开失败"<<endl;return;}cout<<"输入要删除的联系人姓名:";char ch[10];//存储输入的姓名cin>>ch;n=com_name(p,ch);//n代表了联系人的编号cout<<"要删除的联系人编号"<<n<<endl;if(n>=0&&n<num)//姓名存在{k=0;for(i=0;i<num;i++){cout<<"r[i]值"<<r[i]<<"n值"<<n<<endl;if(n!=r[i])//需要删除的数据不输出{outfile<<q[i]<<'\t'<<p[r[i]].name<<'\t'<<p[r[i]].tel_num<<'\t'<<p[r[i]].kind<<'\t'<<p[r[i]].e_mail;k++;}cout<<"k值"<<k<<endl;if(n!=r[i]&&k!=num-1)//k在这里代表的是行数,总共有num-1行,而不是最后一行的标号num-2{cout<<i<<"  "<<k<<"输出回车"<<endl;outfile<<'\n';}}num-=1;//删除数据后的联系人数目cout<<"删除后数据输出完成"<<endl;//这个时候再读一次数据,那么就没有之前要删除的数据了outfile.close();//输出完毕,关闭文件in_data(p,q);//重新读取应该要将原来数据全部清空,我这里没有清空数据,用人数num控制显示,其实后面还是有数据的cout<<"删除后的数据读取完成"<<endl;//此时就应该没有要删除的数据了}elsereturn;//姓名不存在直接返回}void call(linkman *p){cout<<"请输入对方姓名:";char ch[10];cin>>ch;int n;//存放所拨打联系人的编号n=com_name(p,ch);if(n>=0&&n<num)//姓名存在{cout<<"正在呼叫……"<<endl;cout<<"  "<<ch<<"  "<<endl;cout<<p[n].tel_num<<endl;}}

1 0
原创粉丝点击