手机通讯录(结构体实现,链表还不会!)
//global.cpp int 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);//读取数据,并获得联系人数目num count 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.h extern 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 40 typedef 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; } else return;//姓名不存在直接返回 } /****************************************************************** /*删除应该有两种思路,一种,从要删除的文职开始,后面的依次往前覆盖,另一种 /*用先输出,再读入的方式,这里用第一种的话,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;//此时就应该没有要删除的数据了 } else return;//姓名不存在直接返回 } 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; } }
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。