通訊錄至少應該有以下資料項:姓名,地址,手機,郵編,E-mail。
程式的主介面如下:
通訊錄
1. 新增
2. 查詢
4. 排序
5. 全部輸出
0. 退出
#include <iostream>
#include <string>
#include "address.h"
#include "addressList.h"
#include "addressBook.h"
using namespace std;
int main()
{
new AddressBook; //開啟通訊錄
return 0;
}
ostream& operator<<(ostream& os, const RecordList& c_rl)
RecordList::const_iterator it;
RecordList::const_iterator it_end =c_rl.end();
for (it=c_rl.begin();it!=it_end; it++)
os << (*it)->name << "\n" << (*it)->tel << "\n";
return os;
istream& operator>> (istream& is, RecordList& rl)
Record* rec;
string name;
while (true)
//注意這裡使用的是全域性的getline()函式,而不是istream的成員函
//數.全域性的getling()函式將從istream中取出最後一個分隔符,
//而istream的成員函式getline則不會
getline(is,name);
if (name =="")
break;
rec = new Record;
rec->name=name;
getline(is,rec->tel );
rl.push_back(rec);
return is;
#include<stdlib.h>
#include<fstream>
AddressBook::AddressBook()
isModified = false;
start();
AddressBook::~AddressBook()
void AddressBook::start()
cout<<"\n"
<<"\t******************************\n"
<<"\t* 這是一個 *\n"
<<"\t* 簡單的通訊錄程式 *\n"
<<"\t* 可以對通訊錄進行簡單管理 *\n"
<<"\n";
handleMenu();
//功能:顯示通訊錄選單,返回使用者選擇的選項
//返回:使用者選擇的選項,是1-9之間的一個字元
char AddressBook::menuSelect()
<<"1.顯示記錄\n"
<<"2.查詢記錄\n"
<<"3.增加記錄\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
return choice[0];
//功能:根據使用者選擇的專案呼叫相應的處理函式
void AddressBook::handleMenu()
switch(menuSelect())
case "1":
displayRecords();
case "2":
queryRecord();
.......
//功能:列印用於顯示記錄資訊時的表頭
void AddressBook::dispTable()
//功能:顯示通訊錄中的所有記錄
void AddressBook::displayRecords()
//功能:首先檢查通訊錄是否已儲存,然後清空當前通訊錄中所有記錄
//注意:該函式覆蓋了基類中的函式
void AddressBook::clear()
//功能:查詢指定記錄
void AddressBook::queryRecord()
//功能:向當前通訊錄追加新的記錄
//注意:該函式過載了基類中的函式
void AddressBook::addRecord()
/*
//說明:如果使用string 類,效果更好。下面是實現本功能的程式程式碼:
//輸入新記錄
cout<<"姓名:";
getline(cin,name);
//如果輸入的姓名為“0”,則結束新增記錄的操作
if(name=="0")
Record* rec=new Record;
cout<<"電話:";
getline(cin,rec->tel);
//將新記錄加入連結串列
AddressList::addRecord(rec);
//同理,下面的成員函式removeRecord()中的判斷,可以使用如下替代方法:
string str;
getline(cin,str);
if(str[0]!="1" && str[0]!="2")
cout<<"輸入錯誤,重選1-2:";
*/
//功能:從當前通訊錄移除指定的記錄
void AddressBook::removeRecord()
if(empty())
return;
<<"1.透過姓名\n"
<<"2.透過電話\n";
if(choice[0]!="1" && choice[0]!="2")
int type=static_cast<int>(choice[0])-48;
//輸入需要匹配的字串
if(type==1)
cout<<"請輸入姓名:"<<flush;
cout<<"請輸入電話:"<<flush;
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";
if(choice[0]!="n" && choice[0]!="N")
it=AddressList::removeRecord(it);
deletedCount++;
//取下一條匹配的記錄
if(it!=it_end)
it=findRecord(pattern,type,++it);
<<"現在還有"<<size()<<"條記錄"<<endl;
if(deletedCount!=0)
isModified=false;
//功能:將通訊錄儲存至指定檔案
void AddressBook::saveRecords()
cout<<"沒有記錄可存!"<<endl;
//因為下面的程式中使用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;
AddressList::saveRecords(of);
of.close();
cout<<size()<<"條記錄已經存入檔案,請繼續操作。"<<endl;
//功能:從指定檔案讀取記錄追加到當前通訊錄末尾
void AddressBook::loadRecords()
void AddressBook::quit()
#ifndef H_ADDRESSBOOK_H_NNN
#define H_ADDRESSBOOK_H_NNN
//處理通訊錄操作的面向使用者使用的類,包含所有功能的使用者介面及使用者互動的實現
class AddressBook :public AddressList
protected:
bool isModified; //通訊錄是否已被修改還未儲存
public:
AddressBook();
virtual ~AddressBook();
//開始通訊錄的使用者介面操作
virtual void start();
//選單處理函式
virtual void handleMenu();
//顯示記錄
virtual void displayRecords();
//查詢記錄
virtual void queryRecord();
//增加記錄
virtual void addRecord();
virtual void removeRecord();
//儲存記錄
virtual void saveRecords();
//讀取記錄
virtual void loadRecords();
//結束程式
virtual void quit();
//清空當前通訊錄
virtual void clear();
//選單選擇函式
char menuSelect();
//顯示錶頭
void dispTable();
};
#endif //H_ADDRESSBOOK_HZ-NNN
AddressList::~AddressList()
recList.clear();
//功能:向通訊錄中新增新的記錄
//引數:rec,指向新記錄的指標
void AddressList::addRecord (Record* rec)
if (rec !=NULL)
recList.push_back(rec);
//注意:it,應是可提領的迭代器,可以透過findRecord()獲得
AddressList::Iterator AddressList::removeRecord(AddressList::Iterator it)
return recList.erase(it);
//功能:從通訊錄中尋找一個記錄
//引數:pattern,欲尋找的記錄的指定域與pattern相等
// type,為1表示欲尋找記錄的名稱(name)與pattern相等;
// 為2表示欲尋找記錄的電弧(tel)與(pattern)相等。
// from,從from開始尋找匹配的記錄。
//返回:若找到了則返回的迭代器指向第一個匹配記錄的迭代器,
// 若找不到則返回的迭代器等於pastEnd()的返回值。
//注意:from應是可提領的迭代器。
// 第一次呼叫可以用first(),之後使用上一次findRecord()的返回值增1,
// 直到返回pastEnd(),便可以獲得所有匹配的記錄。
AddressList::Iterator AddressList::findRecord(string pattern,int type,AddressList::Iterator from)
Iterator it;
Iterator it_end=recList.end();
for (it=from; it!=it_end; it++)
if ((type==1 && (*it)->name==pattern)||(type==2 && (*it)->tel==pattern))
return it;
//功能:將通訊錄儲存到輸出流中
//引數:os.指定的輸出流
void AddressList::saveRecords(ostream &os)
os << recList;
//功能:從輸入流中讀入資料並追加到當前通訊錄的末尾
//引數:is,指定的輸入流
//返回:讀入的記錄數
int AddressList::loadRecords(istream &is)
int ori =size();
is >> recList;
return size()-ori;
#ifndef H_ADDRESSLIST_H_AAA
#define H_ADDRESSLIST_H_AAA
//處理通訊錄操作的底層類,包括增加記錄、刪
//除記錄、查詢記錄以及儲存和讀取記錄的函式,
//該類不涉及任何關於使用者介面的操作
class AddressList
RecordList recList;// 使用物件成員作為資料成員
typedef RecordList::iterator Iterator;
//向通訊錄中新增新的記錄
virtual void addRecord(Record* rec);
virtual Iterator removeRecord(Iterator it);
//從通訊錄中尋找一個記錄
virtual Iterator findRecord(string pattern,int type,Iterator from);
//將通訊錄儲存到輸出流中
virtual void saveRecords(ostream& os);
//從輸入流中讀入資料並追加到當前通訊錄的末尾
virtual int loadRecords(istream& is);
virtual ~AddressList();
//獲得通訊錄中儲存的記錄數
const int size() const {return (int)recList.size();}
//通訊錄是否為空
const bool empty() const {return recList.empty();}
//清除通訊錄
virtual void clear() {recList.clear();}
//獲得通訊錄的第一條記錄
Iterator first(){return recList.begin();}
//獲得通訊錄超過最後一個記錄之後的迭代器
Iterator pastEnd() {return recList.end();}
#endif //H_ADDRESSLIST_H_AAA
通訊錄至少應該有以下資料項:姓名,地址,手機,郵編,E-mail。
程式的主介面如下:
通訊錄
1. 新增
2. 查詢
4. 排序
5. 全部輸出
0. 退出
#include <iostream>
#include <string>
#include "address.h"
#include "addressList.h"
#include "addressBook.h"
using namespace std;
int main()
{
new AddressBook; //開啟通訊錄
return 0;
}
ostream& operator<<(ostream& os, const RecordList& c_rl)
{
RecordList::const_iterator it;
RecordList::const_iterator it_end =c_rl.end();
for (it=c_rl.begin();it!=it_end; it++)
{
os << (*it)->name << "\n" << (*it)->tel << "\n";
}
return os;
}
istream& operator>> (istream& is, RecordList& rl)
{
Record* rec;
string name;
while (true)
{
//注意這裡使用的是全域性的getline()函式,而不是istream的成員函
//數.全域性的getling()函式將從istream中取出最後一個分隔符,
//而istream的成員函式getline則不會
getline(is,name);
if (name =="")
break;
rec = new Record;
rec->name=name;
getline(is,rec->tel );
rl.push_back(rec);
}
return is;
}
#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"
<<"\n";
handleMenu();
}
//功能:顯示通訊錄選單,返回使用者選擇的選項
//返回:使用者選擇的選項,是1-9之間的一個字元
char AddressBook::menuSelect()
{
cout<<"\n"
<<"1.顯示記錄\n"
<<"2.查詢記錄\n"
<<"3.增加記錄\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;
.......
//功能:列印用於顯示記錄資訊時的表頭
void AddressBook::dispTable()
{
}
//功能:顯示通訊錄中的所有記錄
void AddressBook::displayRecords()
{
}
//功能:首先檢查通訊錄是否已儲存,然後清空當前通訊錄中所有記錄
//注意:該函式覆蓋了基類中的函式
void AddressBook::clear()
{
}
//功能:查詢指定記錄
void AddressBook::queryRecord()
{
//功能:向當前通訊錄追加新的記錄
//注意:該函式過載了基類中的函式
void AddressBook::addRecord()
{
}
/*
//說明:如果使用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);
}
//同理,下面的成員函式removeRecord()中的判斷,可以使用如下替代方法:
string str;
getline(cin,str);
while(true)
{
if(str[0]!="1" && str[0]!="2")
{
cout<<"輸入錯誤,重選1-2:";
getline(cin,str);
}
else
break;
}
*/
//功能:從當前通訊錄移除指定的記錄
//注意:該函式過載了基類中的函式
void AddressBook::removeRecord()
{
if(empty())
{
return;
}
<<"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<<"請輸入姓名:"<<flush;
else
cout<<"請輸入電話:"<<flush;
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";
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);
}
<<"現在還有"<<size()<<"條記錄"<<endl;
if(deletedCount!=0)
isModified=false;
}
//功能:將通訊錄儲存至指定檔案
//注意:該函式過載了基類中的函式
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()
{
}
void AddressBook::quit()
{
}
#ifndef H_ADDRESSBOOK_H_NNN
#define H_ADDRESSBOOK_H_NNN
#include "addressList.h"
//處理通訊錄操作的面向使用者使用的類,包含所有功能的使用者介面及使用者互動的實現
class AddressBook :public AddressList
{
protected:
bool isModified; //通訊錄是否已被修改還未儲存
public:
AddressBook();
virtual ~AddressBook();
//開始通訊錄的使用者介面操作
virtual void start();
//選單處理函式
virtual void handleMenu();
//顯示記錄
virtual void displayRecords();
//查詢記錄
virtual void queryRecord();
//增加記錄
virtual void addRecord();
virtual void removeRecord();
//儲存記錄
virtual void saveRecords();
//讀取記錄
virtual void loadRecords();
//結束程式
virtual void quit();
//清空當前通訊錄
virtual void clear();
protected:
//選單選擇函式
char menuSelect();
//顯示錶頭
void dispTable();
};
#endif //H_ADDRESSBOOK_HZ-NNN
#include "addressList.h"
AddressList::~AddressList()
{
recList.clear();
}
//功能:向通訊錄中新增新的記錄
//引數:rec,指向新記錄的指標
void AddressList::addRecord (Record* rec)
{
if (rec !=NULL)
{
recList.push_back(rec);
}
}
//注意:it,應是可提領的迭代器,可以透過findRecord()獲得
AddressList::Iterator AddressList::removeRecord(AddressList::Iterator it)
{
return recList.erase(it);
}
//功能:從通訊錄中尋找一個記錄
//引數:pattern,欲尋找的記錄的指定域與pattern相等
// type,為1表示欲尋找記錄的名稱(name)與pattern相等;
// 為2表示欲尋找記錄的電弧(tel)與(pattern)相等。
// from,從from開始尋找匹配的記錄。
//返回:若找到了則返回的迭代器指向第一個匹配記錄的迭代器,
// 若找不到則返回的迭代器等於pastEnd()的返回值。
//注意:from應是可提領的迭代器。
// 第一次呼叫可以用first(),之後使用上一次findRecord()的返回值增1,
// 直到返回pastEnd(),便可以獲得所有匹配的記錄。
AddressList::Iterator AddressList::findRecord(string pattern,int type,AddressList::Iterator from)
{
Iterator it;
Iterator it_end=recList.end();
for (it=from; it!=it_end; it++)
{
if ((type==1 && (*it)->name==pattern)||(type==2 && (*it)->tel==pattern))
break;
}
return it;
}
//功能:將通訊錄儲存到輸出流中
//引數:os.指定的輸出流
void AddressList::saveRecords(ostream &os)
{
os << recList;
}
//功能:從輸入流中讀入資料並追加到當前通訊錄的末尾
//引數:is,指定的輸入流
//返回:讀入的記錄數
int AddressList::loadRecords(istream &is)
{
int ori =size();
is >> recList;
return size()-ori;
}
#ifndef H_ADDRESSLIST_H_AAA
#define H_ADDRESSLIST_H_AAA
#include <iostream>
#include <string>
#include "address.h"
using namespace std;
//處理通訊錄操作的底層類,包括增加記錄、刪
//除記錄、查詢記錄以及儲存和讀取記錄的函式,
//該類不涉及任何關於使用者介面的操作
class AddressList
{
protected:
RecordList recList;// 使用物件成員作為資料成員
public:
typedef RecordList::iterator Iterator;
//向通訊錄中新增新的記錄
virtual void addRecord(Record* rec);
virtual Iterator removeRecord(Iterator it);
//從通訊錄中尋找一個記錄
virtual Iterator findRecord(string pattern,int type,Iterator from);
//將通訊錄儲存到輸出流中
virtual void saveRecords(ostream& os);
//從輸入流中讀入資料並追加到當前通訊錄的末尾
virtual int loadRecords(istream& is);
virtual ~AddressList();
//獲得通訊錄中儲存的記錄數
const int size() const {return (int)recList.size();}
//通訊錄是否為空
const bool empty() const {return recList.empty();}
//清除通訊錄
virtual void clear() {recList.clear();}
//獲得通訊錄的第一條記錄
Iterator first(){return recList.begin();}
//獲得通訊錄超過最後一個記錄之後的迭代器
Iterator pastEnd() {return recList.end();}
};
#endif //H_ADDRESSLIST_H_AAA