📄 addressbook.cpp
字号:
#include <stdlib.h>
#include <fstream>
#include "addressbook.h"
using namespace std;
AddressBook::AddressBook()
{
isModified=false;
start();
}
AddressBook::~AddressBook()
{
}
/**********************************************
*功能:显示欢迎画面,并开始进行用户交互处理
***********************************************/
void AddressBook::start()
{
cout<<"\n"
<<"\t******************************\n"
<<"\t* 这是一个 *\n"
<<"\t* 简单的通信录程序 *\n"
<<"\t* 可以对通信录进行简单管理 *\n"
<<"\t* 欢迎使用通信录 *\n"
<<"\t******************************\n"
<<"\n";
handleMenu();
}
/**********************************************
*功能:显示通信录菜单,返回用户选择的选项
*返回:用户选择的选项,是1-9之间的一个字符
***********************************************/
char AddressBook::menuSelect()
{
cout<<"\n"
<<"1.显示记录\n"
<<"2.查询记录\n"
<<"3.增加记录\n"
<<"4.删除记录\n"
<<"5.保存记录\n"
<<"6.读取记录\n"
<<"7.新建通信录\n"
<<"8.结束运行\n"
<<"\n左边数字对应功能选择,请选1-8:";
char choice[2];
while(true)
{
cin.getline(choice,2);
if(choice[0]<'1' || choice[0]>'8')
cout<<"\n输入错误,重选1-8:";
else
break;
}
return choice[0];
}
/**********************************************
*功能:根据用户选择的项目调用相应的处理函数
***********************************************/
void AddressBook::handleMenu()
{
while(true)
{
switch(menuSelect())
{
case '1':
displayRecords();
break;
case '2':
queryRecord();
break;
case '3':
addRecord();
break;
case '4':
removeRecord();
break;
case '5':
saveRecords();
break;
case '6':
loadRecords();
break;
case '7':
clear();
addRecord();
break;
case '8':
quit();
}
}
}
/**********************************************
*功能:打印用于显示记录信息时的表头
***********************************************/
void AddressBook::dispTable()
{
cout<<"姓名\t\t电话"<<endl;
}
/**********************************************
*功能:显示通信录中的所有记录
***********************************************/
void AddressBook::displayRecords()
{
if(recList.size()==0)
{
cout<<"没有记录!";
return;
}
dispTable();
Iterator it;
Iterator it_end=recList.end();
for(it=recList.begin();it!=it_end;it++)
{
cout<<(*it)->name<<"\t\t"<<(*it)->tel<<"\n";
}
cout<<"一共有"<<size()<<"条记录\n"<<endl;
}
/****************************************************************
*功能:首先检查通信录是否已保存,然后清空当前通信录中的所有记录
*注意:该函数覆盖了基类中的函数
*****************************************************************/
void AddressBook::clear()
{
if(isModified)//已改动,未保存
{
cout<<"通信录已改动,是否保存?(y/n)\n";
char choice[2];
cin.getline(choice,2);
if(choice[0]!='n' && choice[0]!='N')
saveRecords();
}
AddressList::clear();
isModified=false;
}
/*************************************
*功能:查询指定记录
**************************************/
void AddressBook::queryRecord()
{
if(empty())
{
cout<<"记录是空表,退出查询操作!"<<endl;
return;
}
//选择获取需要查询的记录的方式
cout<<"可以通过姓名或电话删除记录\n"
<<"1.通过姓名\n"
<<"2.通过电话\n";
char choice[2];
cin.getline(choice,2);
while(true)
{
if(choice[0]!='1' && choice[0]!='2')
{
cout<<"输入错误,重选1-2:";
cin.getline(choice,2);
}
else
break;
}
int type=static_cast<int>(choice[0])-48;
//输入需要匹配的字符串
if(type==1)
cout<<"请输入姓名:";
else
cout<<"请输入电话:";
char pattern[20];
cin.getline(pattern,20);
/*************************************
*这里限制字符串的长度,注意不要越界
*应该使用“string pattern;",但VC 6.0
*不能接受空格,所以采用字符数组形式
**************************************/
int findCount=0;
//找到匹配的记录
Iterator it=findRecord(pattern,type,first());
Iterator it_end=pastEnd();
dispTable();
while(it!=it_end)
{
findCount ++;
cout<<(*it)->name <<"\t\t" <<(*it)->tel <<"\n";
//取下一条匹配的记录
it=findRecord(pattern,type,++it);
}
cout <<"一共找到了"<<findCount<<"条记录\n"<<endl;
}
/****************************************************************
*功能:向当前通信录追加新的记录
*注意:该函数重载了基类中的函数
*****************************************************************/
void AddressBook::addRecord()
{
cout<<"输入数据,输入姓名为0时结束。\n";
while(true)
{
//输入新记录
char temp[20];
cout<<"姓名:";
cin.getline(temp,20);
//如果输入的姓名为“0”,则结束添加记录的操作
if(temp[0]=='0' || temp[0]=='\n')
break;
Record* rec =new Record;
rec->name=temp;
cout <<"电话:";
cin.getline(temp,20);
rec->tel =temp;
//将新记录加入链表
AddressList::addRecord(rec);
};
isModified =true; //记录已改动,未保存
//如果使用string类,效果更好
/*while(true)
{
//输入新记录
string name;
cout<<"姓名:";
getline(cin,name);
//如果输入的姓名为“0”,则结束添加记录的操作
if(name =="0")
break;
Record* rec=new Record;
rec->name=name;
cout<<"电话:";
getline(cin,rec->tel);
//将新记录加入链表
AddressList::addRecord(rec);
};*/
isModified =true;
}
/*************************************
*功能:从当前通信录中移除指定的记录
*注意:该函数重载了基类中的函数
**************************************/
void AddressBook::removeRecord()
{
if(empty())
{
cout<<"通信录已空,退出删除操作!"<<endl;
return ;
}
//选择获取需要删除的记录的方式
cout<<"可以通过姓名或电话删除记录\n"
<<"1.通过姓名\n"
<<"2.通过电话\n";
/*string str;
getline(cin,str);
while(true)
{
if(str[0]!='1' && str[0]!='2')
{
cout <<"输入错误,重选1-2";
getline(cin,str);
}
else
break;
}*/
char choice[2];
cin.getline(choice,2);
while(true)
{
if(choice[0]!='1' && choice[0]!='2')
{
cout<<"输入错误,重选1-2";
cin.getline(choice,2);
}
else
break;
}
int type=static_cast<int>(choice[0])-48;
//输入需要匹配的字符串
if(type==1)
cout<<"请输入姓名:"<<endl;
else
cout<<"请输入电话:"<<endl;
char pattern[20];
cin.getline(pattern,20);
int deletedCount=0;
//找到匹配的记录
Iterator it=findRecord(pattern,type,first());
Iterator it_end=pastEnd();
while(it!=it_end)
{
cout<<"找到一条匹配的记录\n";
dispTable();
cout<<(*it)->name <<"\t\t" <<(*it)->tel <<"\n";
cout<<"确定要删除这条记录吗?[Y/n]";
cin.getline(choice,2);
//删除这条记录
if(choice[0]!='n' && choice[0]!='N')
{
it=AddressList::removeRecord(it);
deletedCount++;
}
//取下一条匹配的记录
if(it!=it_end)
it=findRecord(pattern,type,++it);
}
cout<<"一共删除了"<<deletedCount<<"条记录\n"
<<"现在还有"<<size()<<"条记录"<<endl;
if(deletedCount!=0)
isModified=true;
}
/*************************************
*功能:从当前通信录中移除指定的记录
*注意:该函数重载了基类中的函数
**************************************/
void AddressBook::saveRecords()
{
if(empty())
{
cout<<"没有记录可存!"<<endl;
return ;
}
//因为下面的程序中使用string类的成员函数
//所以需要进行一次转换
string fname;
char name[16];
cout<<"请输入要存入的文件名(直接回车选择文件sname):";
cin.getline(name,16);
fname=name;
if(fname.empty())
fname="sname";
ofstream of(fname.c_str(),ios_base::out);
if(!of)
{
cout<<"不能存入文件!"<<endl;
return ;
}
AddressList::saveRecords(of);
of.close();
cout<<size()<<"条记录已经存入文件,请继续操作。"<<endl;
isModified=false;
}
/*************************************
*功能:从指定文件读取记录追加到当前通信录末尾
*注意:该函数重载了基类中的函数
**************************************/
void AddressBook::loadRecords()
{
string fname;
char name[16];
cout<<"请输入要读取的文件名(直接回车选择文件sname)";
cin.getline(name,16);
fname=name;
if(fname.empty())
fname="sname";
ifstream ifs(fname.c_str(),ios_base::in);
if(!ifs)
{
cout<<"打不开文件!请重新选择"<<endl;
return;
}
bool oriEmpty=empty();
int num=AddressList::loadRecords(ifs);
ifs.close();
cout<<"取入"<<num<<"条记录。\n"
<<"现在通信录中共有"<<size()<<"条记录"<<endl;
//只有加入新记录前通信录不为空并且确实加入了新的记录才改变isModified
if(!oriEmpty && num!=0)
isModified =true;
}
void AddressBook::quit()
{
if(isModified)//已改动,未保存
{
cout<<"通信录已改动,是否保存?(Y/n)\n";
char choice[2];
cin.getline(choice,2);
if(choice[0]!='n' && choice[0]!='N')
saveRecords();
}
cout<<"退出操作,再见!"<<endl;
delete this;
exit(0);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -