这是大一C++课程结业的课程设计,当时写了5天的代码,但也是很爽的过程。因为不好排版主要是个人比较懒,所以比较乱。

 

题目分析

建立两个文本文件,记录存储在手机上联系人的基本信息和存储在手机卡上的联系人的信息。"mymobilelistdata.txt";"mycardlistdata.txt", 系统默认在这两个文件中读写。

建立以下7个类:

1.  手机卡联系人类(Contacts):表示手机卡上的一个联系人

     数据成员包括:

                        姓名(name),电话号码(tel)

      成员函数包括:

                        带参并带默认值的构造函数

                        一组set函数为数据成员赋值: 用string型参数为name和tel赋值

                        一组modify函数,修改数据成员的值:函数实现根据用户选择进行不同信息的修改

                        get函数返回name和tel

                        重载>>,<<运算符,完成对象的输入和输出操作

2.  手机联系人(Mobile_Contacts):公有继承手机卡联系人类,表示手机上的一个联系人

      新增数据成员

                        籍贯(address),QQ号(qq)

成员函数包括

                       一组set函数为数据成员赋值 :内部调用Constacts的set函数

                       一组modify函数,修改数据成员的值 :根据用户选择进行不同信息的修改

                       Get函数返回address,qq

                       重载>>,<<运算符,完成数据成员的输入输出操作

3.  通讯簿抽象类(address_List),用来封装以下函数(为支持多态,以下函数封装为纯虚函数)

                            增加函数(add):添加新的联系人

                            删除操作(removebytel和removebyname):用名字或电话删除一个联系人

                            Display(displayup和displaydown):分别按升序和降序显示所有联系人的信息

                            修改函数(change):输入电话号码,查询到联系人之后进行信息的修改。

                            查询(query): 根据名字查询联系人信息

4.  手机通讯簿类(mobile_list):这是一个数据库类,继承于通讯簿抽象类,用于记录手机中存储的所有联系人的信息

                   数据成员包括:

                            手机联系人的数量(num)

                            手机联系人对象数组 (mymobilelist):用vector动态数组创建。

                   成员函数包括

                            构造函数(mobile_list()):创建fstream类对象instuf,读取文本文件中的数据,并根据文件内容创建联系人对象数组,文件含有标题行4行。

                            析构函数(~mobile_list()):将对象数组中的内容写入到文本文件中。注意只有用户选择0.退出后才会调用析构函数。

                            增加函数(add):增加一个联系人,内部调用重载流插入运算符,且对容量进行判断。

                            删除操作(removebytel和removebyname):用名字或电话删除一个联系人,可以在删除前进行判断,可以重新输入查找信息,可持续删除相同信息的联系人。

                            Display(displayup和displaydown):分别按升序和降序显示所有联系人的信息,调用流提取运算符输出联系人。

                            修改(change):用电话修改联系人,调用联系人类的modify函数,在修改前进行判断,可以重新输入查找信息,可持续修改相同电话的联系人。

                            查询(query):根据名字查询联系人信息,可以重新输入查找信息,可持续查找相同姓名的联系人。

                            String getname(i)和String gettel(i),返回下标为i联系人信息。

                            void  copyset(string pname,string ptel) ,创建pname,ptel联系人压入vector,内部判断联系人是否重复

                            void  clearmobile();清空通讯录

5.  手机卡通信簿(card_list):这是一个数据库类,继承于通讯簿抽象类,用于记录手机卡中存储的所有联系人的信息

                   数据成员包括:

                            手机联系人的数量(num)

                            手机联系人对象数组(mycardlist):用vector动态数组创建

                   成员函数包括

                            构造函数(card_list()):创建fstream类对象instuf,读取文本文件中的数据,并根据文件内容创建联系人对象数组,文件含有标题行4行。

                            析构函数(~card_list()):将对象数组中的内容写入到文本文件中。注意只有用户选择0.退出后才会调用析构函数。

                            增加函数(add):增加一个联系人,内部调用重载流插入运算符,且对容量进行判断。

                            删除操作(removebytel和removebyname):用名字或电话删除一个联系人,在删除前进行判断,可以重新输入查找信息,可持续删除相同信息的联系人。

                            Display(displayup和displaydown):分别按升序和降序显示所有联系人的信息,调用流提取运算符输出联系人。

                            修改(change):用电话修改联系人,调用联系人类的modify函数,在修改前进行判断,可以重新输入查找信息,可持续修改相同电话的联系人。

                            查询(query):根据名字查询联系人信息,可以重新输入查找信息,可持续查找相同姓名的联系人。

                           String getname(i)和Stringgettel(i),返回下标为i联系人信息。

                            void  copyset(string pname,string ptel) ,创建pname,ptel联系人压入vector,内部判断联系人是否重复

                            void  clearcard();清空通讯录

 

6.  用户类(user),这是一个操作类,在主函数中调用用户对象函数,用户对象的函数调用两个通讯录类的函数,完成通讯簿的操作,用户拥有一个两个通讯簿的对象,一个是手机中存储的联系人(mymobile),一个是手机卡中存储的联系人(mycard),并且可以对通讯录进行管理,本程序多态、动态联编的特点都在此类中体现。

                   数据成员包括:

                            两个通讯簿对象和一个menu菜单对象(umenu)。

                   成员函数包括,成员函数体现用户的行为:

                            添加联系人(add):利用基类指针,调用相应的通讯簿对象(手机通讯簿或手机卡通信簿)的增加函数完成联系人的添加。实现动态联编,体现出多态特点。(下同)

                            删除联系人(removebytel和removebyname):调用相应的通讯簿对象的删除操作删除一个联系人

                            Display:显示相应的通讯簿中联系人的信息

                            修改某一联系人的信息(change):调用通讯簿对象的函数完成操作

                            查询并显示某一联系人的信息(query):调用通讯簿对象的函数完成操作

                            将手机卡中的存储的联系人的信息移动到手机中(movectom)

                            将手机中存储的联系人的信息移动到手机卡中(movemtoc)

                            将手机卡中的存储的联系人的信息复制到手机中(copyctom)

                            将手机中存储的联系人的信息复制到手机卡中(copymtoc)

7.  界面菜单类:用来给出不同界面下的操作提示

                   数据成员:无数据成员

                   成员函数:

                            voiddescription(); :显示一些使用建议

                           void mainmenu();     voidaddmenu();

                            void remove1menu();  void changemenu();   void querymenu();

                            void displaymenu();   void displaymenu2();   void displaymenu3();

 

实现代码

         //Contacts.h

//定义手机卡联系人类Contacts,作为手机联系人的基类
#ifndef CONTACTS_H
#define CONTACTS_H
#include<iostream>
#include<string>                                            //若用iostream.h就不能用string
#include<cstring>
using namespace std;
class Contacts {
protected:
	string name,tel;                                        //数据成员有姓名,电话
public:
	Contacts(string pname="Noname",string ptel="Notel");    //带参构造函数
	void set(string pname="Noname",string ptel="Notel");    //set函数为数据成员赋值
	void modify();                                          //按用户需求进行数据修改,所以无参
	string getname();                                       //返回姓名
	string gettel();                                        //返回电话
	friend ostream & operator << (ostream & output,Contacts &);    
	friend istream & operator >> (istream & input,Contacts &);    //重载流插入和流提取运算符
};
#endif

//Contacts.cpp

#include"Contacts.h"
Contacts::Contacts(string pname,string ptel)
{
	name=pname; tel=ptel;
}
inline void Contacts::set(string pname,string ptel)            //有的函数定义内联函数后会出现连接问题
{
	name=pname; tel=ptel;
}
void Contacts::modify()
{
	string pname,ptel;
	char choose;
	cout<<"请选择你要修改的内容:(1.修改姓名和电话号码,2.仅修改姓名,3.仅修改号码)"<<endl;
	cin>>choose;
	switch(choose)
	{
		case '1':
		cout<<"请重新输入姓名 :";
		cin>>pname;
		cout<<"请重新输电话号码 :";
		cin>>ptel;
		name=pname; tel=ptel;
		break;
		case '2':
		cout<<"请重新输入姓名 :";
		cin>>pname;
		name=pname;
		break;
		case '3':
		cout<<"请重新输电话号码 :";
		cin>>ptel;
		tel=ptel;
		break;
		default :
		cout<<"选择错误!修改取消!"<<endl;                   //容错
	}
}
string Contacts::getname()
{return name;}
string Contacts::gettel()
{return tel;}
ostream & operator << (ostream &output,Contacts &obj)         //如果Contacts &前面加const,那么get函数也要是const
{
	output<<"姓名: ";
	output.width(15);                                         //格式控制代替制表符
	output.setf(ios::left);
	output<<obj.getname();output<<"电话号码: "<<obj.gettel()<<endl;
	return output;
}
istream & operator >> (istream & input,Contacts &obj)        //VC6.0编译器限制需要借助get和set函数
{
	string pname,ptel;
	cout<<"请输入姓名 :";
	input>>pname;
	cout<<"请输电话号码 :";
	input>>ptel;
	obj.set(pname,ptel);
	return input;
}
Contacts contactsmark("Noname","Notel");                     //定义Contacts类型结束标志

//Mobile_Contacts.h

//手机联系人类Mobile_Contacts,公有继承Contacts,此类很多内容与contacts类内容相同,此处不再赘述
#ifndef MOBILE_CONTACTS_H
#define MOBILE_CONTACTS_H
#include"Contacts.h"
class Mobile_Contacts : public Contacts
{
protected:
	string address,qq;         //新增数据成员籍贯,QQ
public:
	Mobile_Contacts(string pname="Noname",string ptel="Notel",string paddress="Noaddress",string pqq="Noqq");
	void set(string pname="Noname",string ptel="Notel",string paddress="Noaddress",string pqq="Noqq");
	void modify();             //按用户需求进行数据修改,所以无参
	string getaddress();
	string getqq();
	friend ostream & operator <<(ostream &output,Mobile_Contacts &);
	friend istream & operator >>(istream &input,Mobile_Contacts &);
};
#endif

//Mobile_Contacts.cpp

#include"Mobile_Contacts.h"
Mobile_Contacts::Mobile_Contacts(string pname,string ptel,string paddress,string pqq):Contacts(pname,ptel)
{
	address=paddress; qq=pqq;
}
inline void Mobile_Contacts::set(string pname,string ptel,string paddress,string pqq)
{
	Contacts::set(pname,ptel);                         //调用基类set函数
	address=paddress;
	qq=pqq;
}
void Mobile_Contacts::modify()
{
	string pname,ptel,paddress,pqq;
	char choose;
	cout<<"请选择你要修改的内容:(1.修改全部内容,2.仅修改姓名,3.仅修改号码,4.仅修改籍贯,5.仅修改QQ)"<<endl;
	cin>>choose;
	switch(choose)                                     //匹配不同修改方式
	{
		case '1':
		cout<<"请重新输入姓名 :";
		cin>>pname;
		cout<<"请重新输电话号码 :";
		cin>>ptel;
		cout<<"请重新输入籍贯 :";
		cin>>paddress;
		cout<<"请重新输入QQ :";
		cin>>pqq;
		name=pname; tel=ptel; address=paddress; qq=pqq;
		break;
		case '2':
		cout<<"请重新输入姓名 :";
		cin>>pname;
		name=pname;
		break;
		case '3':
		cout<<"请重新输电话号码 :";
		cin>>ptel;
		tel=ptel;
		break;
		case '4':
		cout<<"请重新输入籍贯 :";
		cin>>paddress;
		address=paddress;
		case '5':
		cout<<"请重新输入QQ :";
		cin>>pqq;
		qq=pqq;
		default :
		cout<<"选择错误!修改取消!"<<endl;
	}
}
inline string Mobile_Contacts::getaddress()
{return address;}
inline string Mobile_Contacts::getqq()
{return qq;}
ostream & operator << (ostream &output,Mobile_Contacts &obj)
{
	output<<"姓名: "; output.width(11);                //格式控制代替制表符
	output.setf(ios::left);
	output<<obj.getname();
	output<<"电话: "; output.width(12);
	output<<obj.gettel();
	output<<"籍贯: "; output.width(12);
	output<<obj.getaddress();
	output<<"QQ号: ";
	output<<obj.getqq()<<endl;
	return output;
}
istream & operator >> (istream & input,Mobile_Contacts & obj)
{
	string pname,ptel,paddress,pqq;
	cout<<"请输入姓名 :";
	input>>pname;
	cout<<"请输电话号码 :";
	input>>ptel;
	cout<<"请输入籍贯 :";
	input>>paddress;
	cout<<"请输入QQ :";
	input>>pqq;
	obj.set(pname,ptel,paddress,pqq);
	return input;
}
Mobile_Contacts mobilecontactsmark("Noname","Notel","Noaddress","NoQQ");              //定义Mobile_Contacts类型结束标志

//Address_List.h

//定义通讯薄抽象类address_list,有如下函数
#ifndef ADDRESS_LIST_H
#define ADDRESS_LIST_H
#include<iostream>
#include<vector>
#include<fstream>
#include<cstring>
#include<string>
using namespace std; 
class address_list {
public:
	virtual void add()=0;                            //添加新的联系人
	virtual void removebytel(string ptel)=0;         //输入电话号码,删除该联系人。
	virtual void removebyname(string pname)=0;       //输入姓名,删除该联系人。
	virtual void change(string ptel)=0;              //输入电话号码,查询到联系人之后进行信息的修改。
	virtual void query(string pname)=0;              //根据名字查询联系人信息
	virtual void displayup()=0;                      //默认按姓名(ASCll码)降序排列
};
#endif

//MobileCrad_Address_list.h

//手机卡通讯录类,继承了抽象类address_list,
#ifndef CARD_LIST_H
#define CARD_LIST_H
#include"Address_List.h"
#include"Contacts.h"
#include<vector>
#include<algorithm>
class card_list : public address_list
{
protected:
	//char *mycardlistfile;         //手机卡通讯录类读写文件
	int num;                        //记录手机卡通讯薄中联系人的数量
	vector<Contacts> mycardlist;    //用户的手机卡联系人对象数组
public:
	card_list();                    //构造函数从文件中读取手机卡联系人写到数组里,供用户进行操作
	void add();
	void removebytel(string ptel);
	void removebyname(string name);
	void change(string ptel);
	void query(string pname);
	void displayup();               //默认按姓名(ASCll码)降序排列
	void displaydown();             //用户可选按姓名(ASCll码)升序排列
	int getnum();                   //返回联系人个数
	string getname(int i);          //返回下标为i的联系人的name
	string gettel(int i);           //返回下标为i的联系人的tel
	void copyset(string pname,string ptel);//创建pname,ptel联系人压入vector
	void clearcard();               //清空通讯录
	~card_list();                   //析构函数将数组写入文件
};
#endif

//MobileCrad_Address_list.cpp

#include"MobileCard_Address_list.h"
#include<cstring>
#include<vector>
extern Contacts contactsmark;                               //引入外部结束标志
const char *mycardlistfile="mycardlistdata.txt";            //系统默认在这个文件中读写
bool comp( Contacts & a, Contacts & b)                      //自定义比较函数,对Contacts类按姓名(ASCll码)升序排列
{
	return a.getname()>b.getname();
}
bool comp2( Contacts & a, Contacts & b)                     //自定义比较函数,对Contacts类按姓名(ASCll码)降序排列
{
	return a.getname()<b.getname();
}
card_list::card_list()
{
	//mycardlistfile=new char[strlen(file)+1];
	//strcpy(mycardlistfile,file);
	num=-1;
	char s[100],pname[30],ptel[30];
	Contacts temp;
	ifstream instuf(mycardlistfile,ios::in);                //建立输入文件流对象
	if(!instuf)
	{
		cerr<<"File could not be open."<<endl;
		abort();
	}
	instuf.getline(s,100);
	instuf.getline(s,100);
	instuf.getline(s,100);
	instuf.getline(s,100);                                 //略去标题行
	while(instuf>>pname>>ptel&&strcmp(pname,"Noname")!=0)
	{
		temp.set(pname,ptel);
		mycardlist.push_back(temp);
		num++;
	}
	instuf.close();
	//sort(mycardlist.begin(),mycardlist.end(),comp);      //此处进行排序并没有用处
	//cout<<"手机卡通讯录中目前共有"<<num+1<<"个联系人."<<endl;
}
void card_list::add()
{
	if(num>999) {cout<<"手机卡通讯录容量已满!无法增加新联系人!"<<endl; return ;}                //已达到容量上限
	Contacts temp;
	cin>>temp;                                             //调用重载>>
	mycardlist.push_back(temp);
	num++;                                                 //加入数组
	cout<<"增加成功!操作完成!"<<endl;
	//sort(mycardlist.begin(),mycardlist.end(),comp);
}
void card_list::removebytel(string ptel)
{
	if(num<0) 
	{
		cout<<"手机卡通讯录当前没有联系人,无法进行删除!"<<endl;
		return ;
	}
	while(1) 
	{
		bool flag=false;
		for(int i=0;i<=num;i++)
		{
			if(mycardlist[i].gettel()==ptel)             //找到了联系人
			{
				flag=true;
				cout<<"将要删除联系人的信息:"<<endl;
				cout<<mycardlist[i];
				cout<<"请确认是否删除:(输入Y确认删除,输入N取消操作)"<<endl;                    //容错
				char chiose;
				cin>>chiose;
				if(chiose=='Y'||chiose=='y') 
				{ mycardlist.erase(mycardlist.begin()+i); num--; cout<<"删除成功!"<<endl;}        //删除
				cout<<"是否继续寻找相同电话号码的联系人?(输入Y确认继续,输入N取消操作)"<<endl;  //容错
				cin>>chiose;
				if(chiose=='Y'||chiose=='y') { continue;}
				else break;
			}
		}
		if(flag==false)									//未找到联系人
		{
			cout<<"在手机卡通讯录没有找到该电话号码对应的联系人!是否重新输入(输入Y确认删除,输入N取消操作)"<<endl; //容错
			char choose; cin>>choose;
			if(choose=='Y'||choose=='y') 
			{cout<<"请重新输入电话号码 :"; cin>>ptel; continue;}
			else  {cout<<"输入取消,删除结束!"<<endl; return;}
		}
		else {cout<<"搜索结束,删除完毕!"<<endl; return;}
	}
	//sort(mycardlist.begin(),mycardlist.end(),comp);
}
void card_list::removebyname(string pname)
{
	if(num==0) 
	{
		cout<<"手机卡通讯录当前没有联系人,无法进行删除!"<<endl;
		return ;
	}
	while(1) 
	{
		bool flag=false;
		for(int i=0;i<=num;i++)
		{
			if(mycardlist[i].getname()==pname)
			{
				flag=true;
				cout<<"将要删除联系人的信息:"<<endl;
				cout<<mycardlist[i];
				cout<<"请确认是否删除:(输入Y确认删除,输入N取消操作)"<<endl;
				char chiose;
				cin>>chiose;
				if(chiose=='Y'||chiose=='y') 
				{ mycardlist.erase(mycardlist.begin()+i); num--;cout<<"删除成功!"<<endl;}
				cout<<"是否继续寻找相同姓名的联系人?(输入Y确认继续,输入N取消操作)"<<endl;
				cin>>chiose;
				if(chiose=='Y'||chiose=='y') { continue;}
				else break;
			}
		}
		if(flag==false)
		{
			cout<<"在手机卡通讯录没有找到该姓名对应的联系人!是否重新输入(输入Y确认删除,输入N取消操作)"<<endl;
			char choose; cin>>choose;
			if(choose=='Y'||choose=='y') {cout<<"请重新输入姓名 :"; cin>>pname; continue;}
			else  {cout<<"输入取消,删除结束!"<<endl; return;}
		}
		else {cout<<"搜索结束,删除完毕!"<<endl; return;}
	}
	//sort(mycardlist.begin(),mycardlist.end(),comp);
}
void card_list::change(string ptel)
{
	if(num<0)  return ;
	while(1)
	{
		bool flag=false;
		for(int i=0;i<=num;i++)
		{
			if(mycardlist[i].gettel()==ptel)
			{
				flag=true;
				cout<<"将要修改联系人的信息:"<<endl;
				cout<<mycardlist[i];
				cout<<"请确认是否修改:(输入Y确认修改,输入N取消操作)"<<endl;
				char chiose;
				cin>>chiose;
				if(chiose=='Y'||chiose=='y') 
				{
					//cin>>mycardlist[i];
					mycardlist[i].modify();                         //为什么不能用modify,函数inline了,在别的文件往往不能连接
					cout<<"修改成功!"<<endl;
				}
				cout<<"是否继续寻找相同电话号码的联系人?(输入Y确认继续,输入N取消操作)"<<endl;
				cin>>chiose;
				if(chiose=='Y'||chiose=='y') { continue;}
				else break;
			}
		}
		if(flag==false) 
		{
			cout<<"在手机卡通讯录没有找到该电话号码对应的联系人!是否重新输入(输入Y确认删除,输入N取消操作)"<<endl;
			char choose; cin>>choose;
			if(choose=='Y'||choose=='y') {cout<<"请重新输入电话号码 :"; cin>>ptel; continue;}
			else  {cout<<"输入取消,修改结束!"<<endl; return;}
		}
		else {cout<<"搜索结束,修改完毕!"<<endl; return;}
	}
	//sort(mycardlist.begin(),mycardlist.end(),comp);
}
void card_list::query(string pname)
{
	if(num<0)  return;
	while(1)
	{
		bool flag=false;
		for(int i=0;i<=num;i++)
		{
			if(mycardlist[i].getname()==pname)
			{
				flag=true;
				cout<<"你要查找联系人的信息:"<<endl;
				cout<<mycardlist[i];
				cout<<"是否继续寻找相同姓名的联系人?(输入Y确认继续,输入N取消操作)"<<endl;
				char chiose; cin>>chiose;
				if(chiose=='Y'||chiose=='y') { continue;}
				else break;
			}
		}
		if(flag==false) 
		{
			cout<<"在手机卡通讯录没有找到该电话号码对应的联系人!是否重新输入(输入Y确认删除,输入N取消操作)"<<endl;
			char choose; cin>>choose;
			if(choose=='Y'||choose=='y') {cout<<"请重新输入姓名 :"; cin>>pname; continue;}
			else  {cout<<"输入取消,查询结束!"<<endl; return;}
		}
		else {cout<<"搜索结束,查询完毕!"<<endl; return;}
	}
}
void card_list::displayup()
{
	if(num<0)  {cout<<"手机卡通讯录当前没有联系人!"<<endl; return;}
	cout<<"手机卡通讯录中目前共有"<<num+1<<"个联系人."<<endl;
	sort(mycardlist.begin(),mycardlist.end(),comp);
	vector<Contacts>::iterator it;
	for(it=mycardlist.begin();it!=mycardlist.end();it++)
	{
		cout<<(*it);
	}
}
void card_list::displaydown()
{
	if(num<0)  {cout<<"手机卡通讯录当前没有联系人!"<<endl; return;}
	cout<<"手机卡通讯录中目前共有"<<num+1<<"个联系人."<<endl;
	sort(mycardlist.begin(),mycardlist.end(),comp2);
	vector<Contacts>::iterator it;
	for(it=mycardlist.begin();it!=mycardlist.end();it++)
	{
		cout<<(*it);
	}
}
int card_list::getnum()
{return num;}
string card_list::getname(int i)        //返回下标为i的联系人的信息
{
    return mycardlist[i].getname();
}
string card_list::gettel(int i)
{
    return mycardlist[i].gettel();
}
void card_list::copyset(string pname,string ptel)
{
    for(int i=0;i<=num;i++)              //避免对相同电话和姓名的联系人再次复制
    {
        if(mycardlist[i].getname()==pname&&mycardlist[i].gettel()==ptel)
        {
            cout<<"已存在姓名为:"<<pname<<" 且电话为:"<<ptel<<" 的联系人!"<<endl;
            return ;
        }
    }
    Contacts temp;
    temp.set(pname,ptel);
    mycardlist.push_back(temp);
    num++;
}
void card_list::clearcard()
{
	mycardlist.clear();
	num=-1;
}
card_list::~card_list()
{
	//sort(mycardlist.begin(),mycardlist.end(),comp);
	ofstream outstuf(mycardlistfile,ios::out);         //建立输入文件流对象
	if(!outstuf)
	{
		cerr<<"File could not be open."<<endl;
		abort();
	}
	outstuf<<"**************************************************"<<endl;
	outstuf<<"*                手机卡通讯录                    *"<<endl;
	outstuf<<"**************************************************"<<endl;
	outstuf<<"姓名"<<"\t\t\t电话号码"<<endl;
	for(int i=num;i>=0;i--)
	{
		outstuf.width(24); outstuf.setf(ios::left);
		outstuf<<mycardlist[i].getname();
		outstuf<<mycardlist[i].gettel()<<endl;
	}
	outstuf<<contactsmark.getname()<<"\t\t\t"<<contactsmark.gettel()<<endl;  //写入结束标志
	outstuf.close();
	mycardlist.clear();
}

//Mobile_Address_list.h

//此文件中的内容类似于Mobile_Card_Address_list.cpp中的内容,一些内容此处不再赘述
//手机通讯录类,继承了抽象类address_list,
#ifndef MOBILE_ADDRESS_LIST_H
#define MOBILE_ADDRESS_LIST_H
#include"Address_List.h"
#include"Mobile_Contacts.h"
#include<vector>
#include<algorithm>
#include<cstring>
#include<string>
class mobile_list : public address_list
{
protected:
	//char *mymobilelistfile;
	int num;                                    //记录手机通讯薄中联系人的数量
	vector<Mobile_Contacts> mymobilelist;       //用户的手机联系人对象数组
public:
	mobile_list();
	void add();
	void removebytel(string ptel);
	void removebyname(string name);
	void change(string ptel);
	void query(string pname);
	void displayup();             
	void displaydown();                         //用户可选按姓名(ASCll码)升序排列
	int getnum();
	string getname(int i);                      //返回下标为i的联系人的name
	string gettel(int i);                       //返回下标为i的联系人的tel
	void copyset(string pname,string ptel);     //创建pname,ptel联系人压入vector
	void clearmobile();                         //清空通讯录
	~mobile_list();                             //析构函数将数组写入文件
};
#endif

//Mobile_Address_list.cpp               

#include"Mobile_Address_list.h"
const char *mymobilelistfile="mymobilelistdata.txt";            //系统默认在这个文件中读写
extern Mobile_Contacts mobilecontactsmark;                      //引入结束标志        
bool comp3( Mobile_Contacts & a, Mobile_Contacts & b)           //自定义比较函数,对Mobile_Contacts类按姓名(ASCll码)降序排列
{
	return a.getname()>b.getname();
}
bool comp4( Mobile_Contacts & a, Mobile_Contacts & b)           //自定义比较函数,对Mobile_Contacts类按姓名(ASCll码)升序排列
{
	return a.getname()<b.getname();
}
mobile_list::mobile_list()
{
	//mymobilelistfile=new char[strlen(file)+1];
	//strcpy(mymobilelistfile,file);
	num=-1;
	char s[100],pname[30],ptel[30],paddress[30],pqq[20];
	Mobile_Contacts temp;
	ifstream instuf(mymobilelistfile,ios::in);                 //建立输入文件流对象
	if(!instuf)
	{
		cerr<<"File could not be open."<<endl;
		abort();
	}
	instuf.getline(s,100);
	instuf.getline(s,100);
	instuf.getline(s,100);
	instuf.getline(s,100);                                     //略去标题行
	while(instuf>>pname>>ptel>>paddress>>pqq&&strcmp(pname,"Noname")!=0)
	{                                                          //提取并放入数组
		temp.set(pname,ptel,paddress,pqq);
		mymobilelist.push_back(temp);
		num++;
	}
	instuf.close();
	//sort(mymobilelist.begin(),mymobilelist.end(),comp3);     
	//cout<<"手机通讯录中目前共有"<<num+1<<"个联系人."<<endl;
}
void mobile_list::add()
{
	if(num>999) {cout<<"手机通讯录容量已满!无法增加新联系人!"<<endl; return ;} //已达到容量上限
	Mobile_Contacts temp;
	cin>>temp;                                                 //调用重载>>
	mymobilelist.push_back(temp);                              //压入数组
	num++;
	cout<<"增加成功!"<<endl;
	//sort(mymobilelist.begin(),mymobilelist.end(),comp3);
}
void mobile_list::removebytel(string ptel)
{
	if(num<0) 
	{
		cout<<"手机通讯录当前没有联系人,无法进行删除!"<<endl;
		return ;
	}
	while(1) 
	{
		bool flag=false;
		for(int i=0;i<=num;i++)
		{
			if(mymobilelist[i].gettel()==ptel)                //找到了联系人
			{
				flag=true;
				cout<<"将要删除联系人的信息:"<<endl;
				cout<<mymobilelist[i];
				cout<<"请确认是否删除:(输入Y确认删除,输入N取消操作)"<<endl;                                   //容错
				char chiose;
				cin>>chiose;
				if(chiose=='Y'||chiose=='y') 
				{ mymobilelist.erase(mymobilelist.begin()+i); num--;cout<<"删除成功!"<<endl; }					  //删除
				cout<<"是否继续寻找相同电话号码的联系人?(输入Y确认继续,输入N取消操作)"<<endl;                 //容错
				cin>>chiose;
				if(chiose=='Y'||chiose=='y') { continue;}
				else break;
			}
		}
		if(flag==false)                                       //未找到联系人
		{
			cout<<"在手机通讯录没有找到该电话号码对应的联系人!是否重新输入(输入Y确认删除,输入N取消操作)"<<endl; //容错
			char choose; cin>>choose;
			if(choose=='Y'||choose=='y') {cout<<"请重新输入电话号码 :"; cin>>ptel; continue;}
			else  {cout<<"输入取消,删除结束!"<<endl; return;}
		}
		else {cout<<"搜索结束,删除完毕!"<<endl; return;}
	}
	//sort(mymobilelist.begin(),mymobilelist.end(),comp3);
}
void mobile_list::removebyname(string pname)
{
	if(num==0) 
	{
		cout<<"手机通讯录当前没有联系人,无法进行删除!"<<endl;
		return ;
	}
	while(1) 
	{
		bool flag=false;
		for(int i=0;i<=num;i++)
		{
			if(mymobilelist[i].getname()==pname)
			{
				flag=true;
				cout<<"将要删除联系人的信息:"<<endl;
				cout<<mymobilelist[i];
				cout<<"请确认是否删除:(输入Y确认删除,输入N取消操作)"<<endl;                  //容错
				char chiose;
				cin>>chiose;
				if(chiose=='Y'||chiose=='y') 
				{ mymobilelist.erase(mymobilelist.begin()+i); num--;cout<<"删除成功!"<<endl; }  //删除
				cout<<"是否继续寻找相同姓名的联系人?(输入Y确认继续,输入N取消操作)"<<endl;    //容错
				cin>>chiose;
				if(chiose=='Y'||chiose=='y') { continue;}
				else break;
			}
		}
		if(flag==false)
		{
			cout<<"在手机通讯录没有找到该姓名对应的联系人!是否重新输入(输入Y确认删除,输入N取消操作)"<<endl; //容错
			char choose; cin>>choose;
			if(choose=='Y'||choose=='y') {cout<<"请重新输入姓名 :"; cin>>pname; continue;}
			else  {cout<<"输入取消,删除结束!"<<endl; return;}
		}
		else {cout<<"搜索结束,删除完毕!"<<endl; return;}
	}
	//sort(mymobilelist.begin(),mymobilelist.end(),comp3);
}
void mobile_list::change(string ptel)
{
	if(num<0)  return ;
	while(1)
	{
		bool flag=false;
		for(int i=0;i<=num;i++)
		{
			if(mymobilelist[i].gettel()==ptel)
			{
				flag=true;
				cout<<"将要修改联系人的信息:"<<endl;
				cout<<mymobilelist[i];
				cout<<"请确认是否修改:(输入Y确认修改,输入N取消操作)"<<endl;
				char chiose;
				cin>>chiose;
				if(chiose=='Y'||chiose=='y') 
				{
					//cin>>mymobilelist[i];
					mymobilelist[i].modify();						//修改
					cout<<"修改成功!"<<endl;
				}
				cout<<"是否继续寻找相同电话号码的联系人?(输入Y确认继续,输入N取消操作)"<<endl;
				cin>>chiose;
				if(chiose=='Y'||chiose=='y') { continue;}
				else break;
			}
		}
		if(flag==false) 
		{
			cout<<"在手机通讯录没有找到该电话号码对应的联系人!是否重新输入(输入Y确认删除,输入N取消操作)"<<endl;
			char choose; cin>>choose;
			if(choose=='Y'||choose=='y') {cout<<"请重新输入电话号码 :"; cin>>ptel; continue;}
			else  {cout<<"输入取消,修改结束!"<<endl; return;}
		}
		else {cout<<"搜索结束,修改完毕!"<<endl; return;}
	}
	//sort(mymobilelist.begin(),mymobilelist.end(),comp3);
}
void mobile_list::query(string pname)
{
	if(num<0)  return ;
	while(1)
	{
		bool flag=false;
		for(int i=0;i<=num;i++)
		{
			if(mymobilelist[i].getname()==pname)
			{
				flag=true;
				cout<<"你要查找联系人的信息:"<<endl;
				cout<<mymobilelist[i];
				cout<<"是否继续寻找相同姓名的联系人?(输入Y确认继续,输入N取消操作)"<<endl;
				char chiose; cin>>chiose;
				if(chiose=='Y'||chiose=='y') { continue;}
				else break;
			}
		}
		if(flag==false) 
		{
			cout<<"在手机通讯录没有找到该姓名对应的联系人!是否重新输入(输入Y确认删除,输入N取消操作)"<<endl;
			char choose; cin>>choose;
			if(choose=='Y'||choose=='y') {cout<<"请重新输入姓名 :"; cin>>pname; continue;}
			else  {cout<<"输入取消,查询结束!"<<endl; return;}
		}
		else {cout<<"搜索结束,查询完毕!"<<endl; return ;}
	}
}
void mobile_list::displayup()
{
	if(num<0)  {cout<<"手机通讯录当前没有联系人!"<<endl; return;}
	cout<<"手机通讯录中目前共有"<<num+1<<"个联系人."<<endl;
	sort(mymobilelist.begin(),mymobilelist.end(),comp3);
	vector<Mobile_Contacts>::iterator it;
	for(it=mymobilelist.begin();it!=mymobilelist.end();it++)
	{
		cout<<(*it);
	}
}
void mobile_list::displaydown()
{
	if(num<0)  {cout<<"手机通讯录当前没有联系人!"<<endl; return;}
	cout<<"手机通讯录中目前共有"<<num+1<<"个联系人."<<endl;
	sort(mymobilelist.begin(),mymobilelist.end(),comp4);
	vector<Mobile_Contacts>::iterator it;
	for(it=mymobilelist.begin();it!=mymobilelist.end();it++)
	{
		cout<<(*it);
	}
}
int mobile_list::getnum()
{return num;}
string mobile_list::getname(int i)
{
    return mymobilelist[i].getname();
}
string mobile_list::gettel(int i)
{
    return mymobilelist[i].gettel();
}
void mobile_list::copyset(string pname,string ptel)
{
    for(int i=0;i<=num;i++)                                                      //避免对相同电话和姓名的联系人再次复制
    {
        if(mymobilelist[i].getname()==pname&&mymobilelist[i].gettel()==ptel)
        {
            cout<<"已存在姓名为:"<<pname<<" 且电话为:"<<ptel<<" 的联系人!"<<endl;
            return ;
        }
    }
    Mobile_Contacts temp;
    temp.set(pname,ptel,"Noaddress","NoQQ");
	mymobilelist.push_back(temp);
	num++;
}
void mobile_list::clearmobile()
{
	mymobilelist.clear();                      
	num=-1;
}
mobile_list::~mobile_list()
{
	//sort(mymobilelist.begin(),mymobilelist.end(),comp3);
	ofstream outstuf(mymobilelistfile,ios::out);           //建立输出文件流对象
	if(!outstuf)
	{
		cerr<<"File could not be open."<<endl;
		abort();
	}
	outstuf<<"***************************************************************"<<endl;
	outstuf<<"*                          手机通讯录                         *"<<endl;
	outstuf<<"***************************************************************"<<endl;
	outstuf<<"姓名"<<"\t\t电话"<<"\t\t籍贯"<<"\t\tQQ"<<endl;
	for(int i=num;i>=0;i--)
	{
		outstuf.setf(ios::left);                            //数组内容写入文件
		outstuf.width(16);  
		outstuf<<mymobilelist[i].getname();
		outstuf.width(16); 
		outstuf<<mymobilelist[i].gettel();
		outstuf.width(16); 
		outstuf<<mymobilelist[i].getaddress();
		outstuf<<mymobilelist[i].getqq()<<endl;
	}
	outstuf.width(16); 
	outstuf<<mobilecontactsmark.getname();
	outstuf.width(16); 
	outstuf<<mobilecontactsmark.gettel();
	outstuf.width(16); 
	outstuf<<mobilecontactsmark.getaddress();
	outstuf<<mobilecontactsmark.getqq()<<endl;             //写入结束标志
	outstuf.close();
	mymobilelist.clear();
}

//menu.h

//定义菜单类显示各种操作界面
#ifndef MENU_H
#define MENU_H
#include<iostream>
using namespace std;
class menu{
public:
	void description();
	void mainmenu();
	void addmenu();
	void remove1menu();
	void changemenu();
	void querymenu();
	void displaymenu();
	void displaymenu2();
	void displaymenu3();
};
#endif

//menu.cpp

#include"menu.h"
void menu::mainmenu()
{
	cout<<"*****************************************************************"<<endl;
	cout<<"*              请输入数字选择相应的操作:                       *"<<endl;
	cout<<"*---------------------------------------------------------------*"<<endl;
	cout<<"*                                                               *"<<endl;
	cout<<"*           0.       退出系统,并保存文件.                      *"<<endl;
	cout<<"*           1.       新建联系人.                                *"<<endl;
	cout<<"*           2.       删除一个联系人.                            *"<<endl;
	cout<<"*           3.       修改联系人的信息.                          *"<<endl;
	cout<<"*           4.       查询联系人信息.                            *"<<endl;
	cout<<"*           5.       浏览所有联系人的信息.                      *"<<endl;
	cout<<"*           6.       将联系人的信息从手机转存到手机卡上.        *"<<endl;
	cout<<"*           7.       将联系人的信息从手机卡上转存到手机上.      *"<<endl;
	cout<<"*****************************************************************"<<endl;
	cout<<"请输入你的选择:"<<endl;
}
void menu::addmenu()
{
	cout<<"**************************************************"<<endl;
	cout<<"*           请选择增加联系人到哪个通讯录:       *"<<endl;
	cout<<"*             1.手机通讯录.                      *"<<endl;
	cout<<"*             2.手机卡通讯录.                    *"<<endl;
	cout<<"**************************************************"<<endl;
	cout<<"请输入你的选择:"<<endl;
}
void menu::remove1menu()
{
	cout<<"**************************************************"<<endl;
	cout<<"*           请选择在哪个通讯录删除联系人:       *"<<endl;
	cout<<"*             1.手机通讯录.                      *"<<endl;
	cout<<"*             2.手机卡通讯录.                    *"<<endl;
	cout<<"*             3.两通讯录都进行删除               *"<<endl;
	cout<<"**************************************************"<<endl;
	cout<<"请输入你的选择:"<<endl;
}
void menu::changemenu()
{
	cout<<"**************************************************"<<endl;
	cout<<"*         请选择在哪个通讯录中修改联系人:       *"<<endl;
	cout<<"*             1.手机通讯录.                      *"<<endl;
	cout<<"*             2.手机卡通讯录.                    *"<<endl;
	cout<<"**************************************************"<<endl;
	cout<<"请输入你的选择:"<<endl;
}
void menu::querymenu()
{
	cout<<"**************************************************"<<endl;
	cout<<"*           请选择在哪个通讯录查询:             *"<<endl;
	cout<<"*             1.手机通讯录.                      *"<<endl;
	cout<<"*             2.手机卡通讯录.                    *"<<endl;
	cout<<"**************************************************"<<endl;
	cout<<"请输入你的选择:"<<endl;
}
void menu::displaymenu()
{
	cout<<"****************************************"<<endl;
	cout<<"*           请选择排序方式:           *"<<endl;
	cout<<"*             1.降序.                  *"<<endl;
	cout<<"*             2.升序.                  *"<<endl;
	cout<<"****************************************"<<endl;
}
void menu::displaymenu2()
{
	cout<<"**************************************************"<<endl;
	cout<<"*                手机卡通讯录                    *"<<endl;
	cout<<"**************************************************"<<endl;
}
void menu::displaymenu3()
{
	cout<<"************************************************************************"<<endl;
	cout<<"*                               手机通讯录                             *"<<endl;
	cout<<"************************************************************************"<<endl;
}
void menu::description()
{
	cout<<"*****************************************************************"<<endl;
	cout<<"*                        Description                            *"<<endl;
	cout<<"*请使用前阅读此说明:                                           *"<<endl;
	cout<<"*        请注意:只有选择0.退出后才能将进行操作后的通讯录保存   *"<<endl;
	cout<<"*    到文件里,直接关闭程序会导致操作内容无效,但原通讯录不会   *"<<endl;
	cout<<"*    丢失。                                                     *"<<endl;
	cout<<"*        系统默认对手机联系人在mymobilelistdata.txt文件中进     *"<<endl;
	cout<<"*    行读写,默认对手机卡联系人在mycardlistdata.txt文件中进     *"<<endl;
	cout<<"*    行读写。                                                   *"<<endl;
	cout<<"*        本系统联系人的信息既可以存储在手机中,也可以存储在手   *"<<endl;
	cout<<"*    机卡中,也可以同时存储在两个位置上,每个位置上的存储容量   *"<<endl;
	cout<<"*    为1000。                                                   *"<<endl;
	cout<<"*        新建,删除,修改,查询都可以选择不同通讯录进行操作。   *"<<endl;
	cout<<"*    删除、修改输入电话号码操作、查询输入姓名操作。             *"<<endl;
	cout<<"*        转存联系人时,对姓名、电话都相同的联系人不进行转存,   *"<<endl;
	cout<<"*    但仅有一项不同时进行转存。                                 *"<<endl;
	cout<<"*        在输入姓名时,请不要在姓名内部加入空格,否则会造成     *"<<endl;
	cout<<"*    不可预料的结果。(其他信息的输入类似。)                   *"<<endl;
	cout<<"*        通讯录中允许相同的联系人存在,但在查询、修改、删除时   *"<<endl;
	cout<<"*    会对提供相同信息的联系人进行全部搜索。                     *"<<endl;
	cout<<"*        请你按菜单提示进行选择,否则会影响你的使用体验!但如   *"<<endl;
	cout<<"*    果你在程序中想结束当前操作时,可以选择屏幕没有提供的选项   *"<<endl;
	cout<<"*    ,这时操作会停止并返回。                                   *"<<endl;
	cout<<"*****************************************************************"<<endl;
}

//user.h

//用户类user,包含两个通讯簿对象数据成员
#ifndef  USER_H
#define  USER_H
#include"menu.h"
#include"Mobile_Address_List.h"
#include"MobileCard_Address_list.h"
class user {
	mobile_list mymobile;          //用户的手机通讯录
	card_list mycard;              //用户的手机卡通讯录
	menu umenu;
public:
	user();
	void add();                    //利用基类指针,调用通讯簿对象的函数完成操作(下同),添加时确定是添加到手机上还是手机卡中
	void removebytel();			   //输入电话号码,删除联系人,如果两个存储位置上都存在该联系人的话,需要在两个存储位置上都要进行删除操作
	void removebyname();		   //输入姓名,删除联系人,如果两个存储位置上都存在该联系人的话,需要在两个存储位置上都要进行删除操作
	void change();				   //输入电话号码,查询到联系人之后进行信息的修改。如果两个存储位置上都存在该联系人的话,需要在两个存储位置上都要进行删除操作
	void query();                  //输入姓名,查询联系人,两个通讯录都进行查询
	void display();                //显示两个通讯簿中联系人的信息
	void copyctom();               //将手机卡中的存储的联系人的信息复制到手机中
	void copymtoc();               //将手机中存储的联系人的信息复制到手机卡中
	void movectom();               //将手机卡中的存储的联系人的信息移动到手机中
	void movemtoc();               //将手机中存储的联系人的信息移动到手机卡中  (之前的就没了)
	~user();
};
#endif

//user.cpp

#include"User.h"
user::user()
{
	cout<<"*=====================================================================*"<<endl;
	cout<<"     欢迎使用会员卡管理系统!已从相关文件中为你读取了联系人信息!    "<<endl;
	cout<<"*---------------------------------------------------------------------*"<<endl;
	cout<<"          你的手机通讯录中目前共有"<<mymobile.getnum()+1<<"个联系人. "<<endl;
	cout<<"*---------------------------------------------------------------------*"<<endl;
	cout<<"          你的手机卡通讯录中目前共有"<<mycard.getnum()+1<<"个联系人. "<<endl;
	cout<<"*=====================================================================*"<<endl;
}
void user::add()
{
	umenu.addmenu();                         //显示菜单
	address_list *temp;                      //创建基类指针
	char choose;
	cin>>choose;
	cout<<"*=============================================================================*"<<endl;
	switch(choose)
	{
	case '1':
		temp=&mymobile;                      //基类指针指向派生类对象
		temp->add();                         //调用派生类函数
		break;
	case '2':
		temp=&mycard;
		temp->add();						 //基类指针指向派生类对象
		break;
	default:
		cout<<"选择错误!操作结束!"<<endl;
		return;
	}
	cout<<"*=============================================================================*"<<endl;
}
void user::removebytel()
{
	umenu.remove1menu();
	address_list *temp;
	char choose; 
	string ptel; 
	cin>>choose;
	cout<<"*=============================================================================*"<<endl;
	switch(choose)
	{
	case '1':
		if(mymobile.getnum()<0) {cout<<"手机通讯录当前没有联系人,无法进行删除!"<<endl; break;}
		cout<<"请输入要删除联系人的电话:"<<endl;
		cin>>ptel;
		temp=&mymobile;
		temp->removebytel(ptel);
		break;
	case '2':
		if(mycard.getnum()<0) {cout<<"手机卡通讯录当前没有联系人,无法进行删除!"<<endl; break;}
		cout<<"请输入要删除联系人的电话:"<<endl;
		cin>>ptel;
		temp=&mycard;
		temp->removebytel(ptel);
		break;
	case '3':
		cout<<"请输入要删除联系人的电话:"<<endl;
		cin>>ptel;
		cout<<"<下面是在手机通讯录中进行的删除操作>"<<endl;
		temp=&mymobile;
		temp->removebytel(ptel);
		cout<<"<下面是在手机卡通讯录中进行的删除操作>"<<endl;
		temp=&mymobile;
		temp->removebytel(ptel);
	default:
		cout<<"选择错误!操作结束!"<<endl;
	}
	cout<<"*=============================================================================*"<<endl;
}
void user::removebyname()
{
	umenu.remove1menu();
	address_list *temp;
	char choose; 
	string pname; 
	cin>>choose;
	cout<<"*=============================================================================*"<<endl;
	switch(choose)
	{
	case '1':
		if(mymobile.getnum()<0) {cout<<"手机通讯录当前没有联系人,无法进行删除!"<<endl; break;}
		cout<<"请输入要删除联系人的姓名:"<<endl;
		cin>>pname;
		temp=&mymobile;
		temp->removebyname(pname);
		break;
	case '2':
		if(mycard.getnum()<0) {cout<<"手机卡通讯录当前没有联系人,无法进行删除!"<<endl; break;}
		cout<<"请输入要删除联系人的姓名:"<<endl;
		cin>>pname;
		temp=&mycard;
		temp->removebyname(pname);
		break;
	case '3':
		cout<<"请输入要删除联系人的姓名:"<<endl;
		cin>>pname;
		cout<<"<下面是在手机通讯录中进行的删除操作>"<<endl;
		temp=&mymobile;
		temp->removebyname(pname);
		cout<<"<下面是在手机卡通讯录中进行的删除操作>"<<endl;
		temp=&mymobile;
		temp->removebyname(pname);
	default:
		cout<<"选择错误!操作结束!"<<endl;
	}
	cout<<"*=============================================================================*"<<endl;
}
void user::change()
{
	umenu.changemenu();
	address_list *temp;
	char choose; string ptel;
	cin>>choose;
	cout<<"*=============================================================================*"<<endl;
	switch(choose)
	{
	case '1':
		if(mymobile.getnum()<0) {cout<<"手机通讯录当前没有联系人,无法进行修改!"<<endl; break;}
		cout<<"请输入要修改联系人的电话:"<<endl;
		cin>>ptel;
		temp=&mymobile;
		temp->change(ptel);
		break;
	case '2':
		if(mycard.getnum()<0) {cout<<"手机卡通讯录当前没有联系人,无法进行修改!"<<endl; break;}
		cout<<"请输入要修改联系人的电话:"<<endl;
		cin>>ptel;
		temp=&mycard;
		temp->change(ptel);
		break;
	default:
		cout<<"选择错误!操作结束!"<<endl;
	}
	cout<<"*=============================================================================*"<<endl;
}
void user::query()
{
	umenu.querymenu();
	address_list *temp;
	char choose; string pname;
	cin>>choose;
	cout<<"*=============================================================================*"<<endl;
	switch(choose)
	{
	case '1':
		if(mymobile.getnum()<0) {cout<<"手机通讯录当前没有联系人!"<<endl; break;}
		cout<<"请输入要查询联系人的姓名:"<<endl;
		cin>>pname;
		temp=&mymobile;
		temp->query(pname);
		break;
	case '2':
		if(mycard.getnum()<0) {cout<<"手机卡通讯录当前没有联系人!"<<endl; break;}
		cout<<"请输入要查询联系人的姓名:"<<endl;
		cin>>pname;
		temp=&mycard;
		temp->query(pname);
		break;
	default:
		cout<<"选择错误!操作结束!"<<endl;
	}
	cout<<"*=============================================================================*"<<endl;
}
void user::display()
{
	umenu.displaymenu();
	address_list *temp;
	char choose;
	cin>>choose;
	cout<<"*=============================================================================*"<<endl;
	switch(choose)
	{
	case '1':
		umenu.displaymenu2();
		temp=&mycard;
		temp->displayup();
		umenu.displaymenu3();
		temp=&mymobile;
		temp->displayup();
		break;
    case '2':
        umenu.displaymenu2();
		mycard.displaydown();  //displaydown函数不是继承来的
		umenu.displaymenu3();
		mymobile.displaydown();
        break;
    default :
        cout<<"选择错误!操作结束!"<<endl;
        break;
	}
	cout<<"*=============================================================================*"<<endl;
}
void user::copymtoc()
{
	cout<<"*=============================================================================*"<<endl;
	if(mymobile.getnum()<0) {cout<<"手机通讯录当前没有联系人!"<<endl; return;}
    for(int i=0;i<=mymobile.getnum();i++)
    {
		if(mycard.getnum()>999) {cout<<"手机通讯录容量已满!无法增加新联系人!"<<endl; return ;}
        mycard.copyset(mymobile.getname(i),mymobile.gettel(i));
    }
	cout<<"操作成功!"<<endl;
	cout<<"*=============================================================================*"<<endl;
}
void user::copyctom()
{
	cout<<"*=============================================================================*"<<endl;
	if(mycard.getnum()<0) {cout<<"手机卡通讯录当前没有联系人!"<<endl; return;}
    for(int i=0;i<=mycard.getnum();i++)
    {
		if(mycard.getnum()>999) {cout<<"手机通讯录容量已满!无法增加新联系人!"<<endl; return ;}
        mymobile.copyset(mycard.getname(i),mycard.gettel(i));
    }
	cout<<"操作成功!"<<endl;
	cout<<"*=============================================================================*"<<endl;
}
void user::movemtoc()
{
	cout<<"*=============================================================================*"<<endl;
	if(mymobile.getnum()<0) {cout<<"手机通讯录当前没有联系人!"<<endl; return;}
	for(int i=0;i<=mymobile.getnum();i++)
    {
		if(mymobile.getnum()>999) {cout<<"手机卡通讯录容量已满!无法增加新联系人!"<<endl; return ;}
        mycard.copyset(mymobile.getname(i),mymobile.gettel(i));
    }
	mymobile.clearmobile();
	cout<<"操作成功!"<<endl;
	cout<<"*=============================================================================*"<<endl;
}
void user::movectom()
{
	cout<<"*=============================================================================*"<<endl;
	if(mycard.getnum()<0) {cout<<"手机卡通讯录当前没有联系人!"<<endl; return;}
    for(int i=0;i<=mycard.getnum();i++)
    {
		if(mymobile.getnum()>999) {cout<<"手机卡通讯录容量已满!无法增加新联系人!"<<endl; return ;}
        mymobile.copyset(mycard.getname(i),mycard.gettel(i));
    }
	mycard.clearcard();
	cout<<"操作成功!"<<endl;
	cout<<"*=============================================================================*"<<endl;
}
user::~user()
{cout<<"谢谢使用本系统!您的联系人已存入相关文件中!"<<endl;}

//main.cpp

#include"menu.h"
#include"User.h"
#include"Address_List.h"
#include"Mobile_Contacts.h"
#include"MobileCard_Address_list.h"
#include"Mobile_Address_List.h"
int main()
{
	menu mymenu;                            //菜单类
	user me;                                //实现user类对象,实现各种操作
	mymenu.description();
	system("pause");
	system("cls");
	char choose='1';
	char c;
	while(choose!='0')
	{
		mymenu.mainmenu();
		cin>>choose;
		switch(choose)
		{
		case '0': break;                     //保存文件,退出
		case '1':
			me.add();                        //增加
			break;
		case '2':
			cout<<"请选择操作方式: 1.按电话删除,2.按姓名删除."<<endl;
			cin>>c;
			switch(c)
			{
			case '1':
				me.removebytel();             //用tel删除
				break;
			case '2':
				me.removebyname();            //用name删除
				break;
			default:
				cout<<"选择错误!"<<endl;     //用户不想继续操作时,可以错误选择来退出。
				break;
			}
			break;
		case '3':
			me.change();                      //修改
			break;
		case '4':
			me.query();                       //查询
			break;
		case '5':
			me.display();                     //浏览
			break;
		case '6':
			cout<<"请选择操作方式: 1.复制,2.移动."<<endl;
			cin>>c;
			switch(c)
			{
			case '1':
				me.copymtoc();                //将手机中存储的联系人的信息复制到手机卡中
				break;
			case '2':
				me.movemtoc();                //将手机中存储的联系人的信息移动到手机卡中
				break;
			default :
				cout<<"选择错误!"<<endl;
			}
			break;
		case '7':
			cout<<"请选择操作方式: 1.复制,2.移动."<<endl;
			cin>>c;
			switch(c)
			{
			case '1':
				me.copyctom();                 //将手机卡中的存储的联系人的信息复制到手机中
				break;
			case '2':
				me.movectom();                 //将手机卡中的存储的联系人的信息移动到手机中
				break;
			default :
				cout<<"选择错误!"<<endl;
			}
			break;
		default :
			cout<<"选择错误!"<<endl;
		}
		system("pause");
		system("cls");
	}
	return 0;
}


使用说明:

                       请注意:只有选择0.退出后才能将进行操作后的通讯录保存到文件里,直接关闭程序会导致操作内容无效,但原通讯录不会丢失。

                       系统默认对手机联系人在mymobilelistdata.txt文件中进行读写,默认对手机卡联系人在mycardlistdata.txt文件中进行读写。

                       本系统联系人的信息既可以存储在手机中,也可以存储在手机卡中,也可以同时存储在两个位置上,每个位置上的存储容量为1000。

                       新建,删除,修改,查询都可以选择不同通讯录进行操作。删除、修改输入电话号码操作、查询输入姓名操作。

                       转存联系人时,对姓名、电话都相同的联系人不进行转存,但仅有一项不同时进行转存。

                       在输入姓名时,请不要在姓名内部加入空格,否则会造成不可预料的结果。(其他信息的输入类似。)

                       通讯录中允许相同的联系人存在,但在查询、修改、删除时会对提供相同信息的联系人进行全部搜索,也就是可以对删除的对象进行选择。下图是修改时部分界面:


                       请按菜单提示进行选择,否则会影响你的使用体验!但如果你在程序中想结束当前操作时,可以选择屏幕没有提供的选项,这时操作会停止并返回。

 

总结

1.此程序为了方便用了c++中封装好的string类,由于VC6.0中重载流提取和流插入运算符要把#include<iostream> using namespacestd;改为#include <iostream.h> ,但这样更改后不能使用<string>,所以在重载>>,<<时内部用get和set函数进行相关操作,但经过验证若将此程序修改相应部分后用codeblocks可编译成功。

2.此程序对文件采用文本文件的方式进行读写。要注意只有选择0.退出后才能将进行操作后的通讯录保存到文件里,直接关闭程序会导致操作内容无效,但原通讯录不会丢失。

3.作为一个有很多选择的系统,想要它对每次选择都有一个好的容错性是很复杂的。最直接的方法就是在选错后进行退出。一个良好的程序应该能对错误的操作也有正确的反应。

4.在编辑过程中有些函数如果定义为内联函数,则在其他文件中使用时会出现连接错误的问题,此问题只要去掉前缀inline就解决了。

5.在函数参数中如:void function(const Contacts &obj,……),此时函数内部不能调用非常函数,解决方法是去掉const,因为对于这种小程序来说加const也没用,还有方法就是将其内部调用的函数改为常函数,但此方法改动大且容易引发其他问题。

6.在输出时使用制表符存在因字符长度不同而不能对其的情况,此问题可以将制表符换为cout.width(15)控制格式来解决。

7.继承自抽象类的函数一定都得在派生类中重定义。否则编译不会成功。

8.对于头文件的redefination,可以对每个头文件中都使用条件编译。

9.带默认值的构造函数,一定在声明时给出默认值,而定义时的形参中不能带默认值。

10.使用分割线使每步操作间进行区分,对每步操作成功与否进行反馈,能使程序更容易调试。

11.在提供选择时,代码部分为int choose,switch(choose),这样的话如果用户选择时输入了字母,即便有default语句也不能进行退出,但若把choose定义为char那么就可以通过default语句安全退出。

最后说一下心得体会吧:学习C++一年了,是第一次写这么复杂的程序,但也是有很多学过的知识没能运用到程序中。写程序过程中感觉还好,没有遇到什么复杂的问题,但在写完程序后会发现,一个程序越复杂,它的优化是没有结束的,你总会发现它的不足,总想再改些东西。而且由于编程经验不足,所以也没有太多自己独特的想法加入这个程序。虽然这个程序是不足的,但也很高兴能把它做出来,也感谢上过的每一节c++课。


Logo

快速构建 Web 应用程序