?? communications.txt
字號:
/*☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆
C++課程設計--通訊錄管理程序
作者:韓道儒
學號:020510610
完成時間:2006.6.18
☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆*/
#include
#include
#include
#include
#include
#include
void DisplayMenu()//主菜單
{
char *menu[]={"\t\t\t1.增加記錄",
"\t\t\t2.刪除記錄",
"\t\t\t3.顯示所有記錄",
"\t\t\t4.按姓名查找并顯示一個記錄",
"\t\t\t5.按姓名查找并修改一個記錄",
"\t\t\t6.從正文文件中添加數據到庫表中",
"\t\t\t7.將庫表中的數據寫入正文文件",
"\t\t\t8.排序庫表\n\n",
"\t\t\t9.退出系統",
NULL};
cout<<"\n\n\t\t★★★★★歡迎使用通訊錄管理系統!★★★★★ \n\n";
for(int i=0; menu[i]; i++) cout< cout<<"\n\t\t★★★★★★★★★★★★★★★★★★★★★★\n";
cout<<"請輸入相應功能的序號:";
}
//功能5有子菜單:
void ShowModiMenu()
{ char *submenu[]={"(1) 修改姓名",
"(2) 修改辦公室電話",
"(3) 修改住宅電話",
"(4) 修改手機號碼",
"(5) 修改email地址\n",
"(0) 不修改,返回主菜單",
NULL};
cout< for(int i=0; submenu[i]; i++) cout< cout<<"請輸入選擇:";
}
//結點類
class Node
{
char Name[10];//姓名
char OfficePhone[15];//辦公室電話
char HomePhone[15];//住宅電話
char MobilePhone[15];//手機號碼
char EMail[20];//email地址
Node *Next;//下一結點指針
public:
Node(char *pname=NULL, char *ophone=NULL, char *hphone=NULL,
char *pmphone=NULL, char *pemail=NULL)
//構造函數,各參數均有缺省值
{
if(pname) strcpy(Name, pname);
else strcpy(Name, " ");
if(ophone) strcpy(OfficePhone, ophone);
else strcpy(OfficePhone, " ");
if(hphone) strcpy(HomePhone, hphone);
else strcpy(HomePhone, " ");
if(pmphone) strcpy(MobilePhone, pmphone);
else strcpy(MobilePhone, " ");
if(pemail) strcpy(EMail, pemail);
else strcpy(EMail, " ");
}
void Show()//顯示結點數據
{
cout< <<"(O)"< < }
void SetName(char *s)//修改姓名
{strcpy(Name, s);}
void SetOfficePhone(char *op)//修改辦公室電話
{strcpy(OfficePhone, op);}
void SetHomePhone(char *hp)//修改住宅電話
{strcpy(HomePhone, hp);}
void SetMobilePhone(char *s)//修改手機號碼
{strcpy(MobilePhone, s);}
void SetEMail(char *s)//修改email地址
{strcpy(EMail, s);}
friend class AddrList;//將AddrList類說明為友元類
friend void addfromtxtfile(AddrList &);//將addfromtxtfile說明為友元函數
friend void writetotxtfile(AddrList &);//將writetotxtfile說明為友元函數
};
//鏈表類
class AddrList
{
Node *HeadPtr;//鏈表首指針
Node *TailPtr;//鏈表尾指針
int Tag;//排序狀態標志,當Tag=1時,按姓名排序
//當Tag=2時,按辦公室電話排序
public:
//成員函數
AddrList(Node *head=NULL, Node *tail=NULL, int tag=1)
//構造函數,產生空鏈表,將tag的值置為1
{
HeadPtr=head;
TailPtr=tail;
Tag=tag;
}
void AddTail(Node *p)//將p指向的結點加入到鏈表尾部
{
if(HeadPtr==NULL)
{
HeadPtr=p;
TailPtr=p;
p->Next=NULL;
}
else
{
TailPtr->Next=p;
p->Next=NULL;
TailPtr=p;
}
}
void AddSort(Node *p)//將p指向的結點按Tag指定的順序插入到鏈表中
{
Node *p1, *p2;
if(Tag==1)//按姓名排序
{
if(HeadPtr==NULL)//如果插入前原始鏈表為空鏈表
{
HeadPtr=p;
TailPtr=p;
p->Next=NULL;
}
else
{
if(strcmp(p->Name, HeadPtr->Name)<=0)//插在鏈表首部
{
p->Next=HeadPtr;
HeadPtr=p;
}
else//插在鏈表中間或尾部
{
p1=HeadPtr;
p2=HeadPtr;
while(p2->Next&&(strcmp(p2->Name, p->Name)<0))
//查找待插入位置
{p1=p2; p2=p2->Next;}
if(strcmp(p2->Name, p->Name)<0)//插在鏈表尾部
{p2->Next=p; p->Next=NULL; TailPtr=p;}
else//插在鏈表中間,p2之前
{p->Next=p2; p1->Next=p;}
}
}
}
else//按辦公室電話排序
{
if(HeadPtr==NULL)//如果插入前原始鏈表為空鏈表
{
HeadPtr=p;
TailPtr=p;
p->Next=NULL;
}
else
{
if(strcmp(p->OfficePhone, HeadPtr->OfficePhone)<=0)//插在鏈表首部
{
p->Next=HeadPtr;
HeadPtr=p;
}
else//插在鏈表中間或尾部
{
p1=HeadPtr;
p2=HeadPtr;
while(p2->Next&&(strcmp(p2->OfficePhone, p->OfficePhone)<0))
//查找待插入位置
{p1=p2; p2=p2->Next;}
if(strcmp(p2->OfficePhone, p->OfficePhone)<0)//插在鏈表尾部
{p2->Next=p; p->Next=NULL; TailPtr=p;}
else//插在鏈表中間,p2之前
{p->Next=p2; p1->Next=p;}
}
}
}
}
Node *LookUp(char *name)//按姓名查找結點,返回該結點指針
{
Node *p;
p=HeadPtr;
while(p!=NULL)
{
if(strcmp(p->Name, name)==0) return p;
p=p->Next;
}
return NULL;
}
void 刪除(char *name)//刪除指定姓名的結點
{
Node *p1, *p2;
if(strcmp(HeadPtr->Name, name)==0)//若待刪除的結點為首結點
{
p1=HeadPtr;
HeadPtr=HeadPtr->Next;
刪除 p1;
cout<<"刪除了聯系人"< system("pause");
}
else//刪除其他結點
{
p1=HeadPtr;
p2=HeadPtr;
while(strcmp(p2->Name, name)!=0&&p2->Next!=NULL)
{
p1=p2;
p2=p2->Next;
}
if(strcmp(p2->Name, name)==0)
{
p1->Next=p2->Next;
刪除 p2;
cout<<"刪除了一個聯系人的信息!"< system("pause");
}
}
}
void Sort(int tag)//按tag指定的關鍵字重新排序
{
Node *p1, *p2;
Tag=tag;
p2=HeadPtr;
HeadPtr=NULL;
TailPtr=NULL;
while(p2)
{
p1=p2->Next;
AddSort(p2);
p2=p1;
}
TailPtr->Next=NULL;
}
void ShowAll()//顯示全部結點,每10個顯示一屏
{
int n=0;
Node *p;
if(HeadPtr==NULL)
{
cout<<"鏈表為空,沒有記錄可顯示!"< }
else for(p=HeadPtr; p!=NULL; p=p->Next)
{
p->Show();
n++;
if(n%10==0) {cout<<"按任意鍵顯示下一屏:"< }
}
void SetTag(int t)//置Tag值
{Tag=t;}
int GetTag()//取tag值
{return Tag;}
Node *GetHeadPtr()//取首指針
{return HeadPtr;}
~AddrList()//釋放鏈表空間
{
Node *p;
if(HeadPtr==NULL) ;
else
{
while(HeadPtr)
{
p=HeadPtr;
HeadPtr=HeadPtr->Next;
刪除 p;
}
}
}
void CreateList(char *filename)//從二進制文件中讀入數據,
//構造鏈表
{
ifstream infile(filename, ios::in|ios::binary|ios::nocreate);
if(!infile) {cout<<"文件"< //如果文件不存在,直接返回,空表
else
{
infile.read((char *)&Tag, 4);//讀出二進制文件的第1個數據Tag
int n;
infile.read((char *)&n, 4);//讀出記錄數
cout<<"正在從數據中加載"< Node *p;
for(int i=0; i {
p=new Node;
infile.read((char *)p, sizeof(Node));
AddTail(p);
}
}
infile.close();
cout<<"數據從二進制文件加載成功!"< }
void WriteToFile(char *filename)//將鏈表中數據
//寫入指定的二進制文件
{
ofstream outfile;
outfile.open(filename, ios::out|ios::binary);
outfile.write((char *)&Tag, 4);
Node *p, *p1;
int n=0;
for(p1=HeadPtr; p1!=NULL; p1=p1->Next) n++;
outfile.write((char *)&n, 4);
p=HeadPtr;
while(p)
{
outfile.write((char *)p, sizeof(Node));
p=p->Next;
}
cout<<"成功導出二進制文件!共有"< outfile.close();
}
};
//以下為處理函數
void add(AddrList &addrlist)//增加記錄,按照當前排序標志Tag
//插入結點,插入結點后,鏈表仍然
//保持有序
{
cout<<"請輸入姓名、辦公室電話、住宅電話、手機號碼、email地址(以空格、Tab或回車分隔):"
< char n[10], op[15], hp[15], mp[15], em[20];
cin>>n>>op>>hp>>mp>>em;
Node *p;
p=new Node(n, op, hp, mp, em);
p->Show();
addrlist.AddSort(p);
cout<<"添加成功!是否繼續添加?[y/n]";
char t;
cin>>t;
if(t=='y') add(addrlist);
}
void del(AddrList &addrlist)//刪除記錄
{
if(addrlist.GetHeadPtr()==NULL)
{cout<<"鏈表為空,沒有記錄可刪!"< cout<<"請輸入要刪除的聯系人的姓名:";
char n[10]; cin>>n;
Node *p;
p=addrlist.LookUp(n);
if(p==NULL) {cout<<"鏈表上沒有聯系人"< p->Show();
cout<<"確認刪除?[y/n]";
char t;
cin>>t;
if(t=='y') addrlist.刪除(n);
}
void showall(AddrList &addrlist)//顯示所有記錄
{
addrlist.ShowAll();
system("pause");
}
void query(AddrList &addrlist)//按姓名查找并顯示一條記錄
{
if(addrlist.GetHeadPtr()==NULL)
{cout<<"鏈表為空,沒有聯系人可查找!"< cout<<"請輸入要查找的聯系人的姓名:";
char n[10]; cin>>n;
Node *p;
p=addrlist.LookUp(n);
if(p==NULL)
{cout<<"沒有"< cout<<"該聯系人的記錄為:"< p->Show();
system("pause");
}
void modify(AddrList &addrlist)//按姓名修改一條記錄
//當修改姓名后,如果當前排序關鍵字
//為姓名,需重新排序。當修改辦公室
//電話后,如果當前排序關鍵字為辦公室
//電話,需重新排序。
{
if(addrlist.GetHeadPtr()==NULL)
{cout<<"鏈表為空,沒有記錄可修改!"< cout<<"請輸入要修改的聯系人的姓名:";
char n[10]; cin>>n;
Node *p;
p=addrlist.LookUp(n);
if(p==NULL)
{cout<<"沒有"< cout<<"該聯系人的記錄為:"< p->Show();
ShowModiMenu();
int m, state;
cin>>m;
state=cin.rdstate();
while(state||((m<1||m>5)&&m!=0))
{
cout<<"請重新輸入選擇:"< if(state) {char str[80]; cin.clear(); cin.getline(str, 80);}
cin>>m;
state=cin.rdstate();
}
if(m==1)//修改姓名
{
cout<<"請輸入修改后的姓名:"; char n[10];
cin>>n; p->SetName(n); cout<<"修改成功!新的記錄為:"< p->Show();
if(addrlist.GetTag()==1) addrlist.Sort(1);//判斷是否需要重新排序
system("pause");
}
else if(m==2)//修改辦公室電話
{
cout<<"請輸入修改后的辦公室電話:"; char op[15];
cin>>op; p->SetOfficePhone(op); cout<<"修改成功!新的記錄為:"< p->Show();
if(addrlist.GetTag()==2) addrlist.Sort(2);//判斷是否需要重新排序
system("pause");
}
else if(m==3)//修改住宅電話
{
cout<<"請輸入修改后的住宅電話:"; char hp[15];
cin>>hp; p->SetHomePhone(hp); cout<<"修改成功!新的記錄為:"< p->Show();
system("pause");
}
else if(m==4)//修改手機號碼
{
cout<<"請輸入修改后的手機號碼:"; char mp[15];
cin>>mp; p->SetMobilePhone(mp); cout<<"修改成功!新的記錄為:"< p->Show();
system("pause");
}
else if(m==5)//修改email地址
{
cout<<"請輸入修改后的email地址:"; char em[20];
cin>>em; p->SetEMail(em); cout<<"修改成功!新的記錄為:"< p->Show();
system("pause");
}
else if(m==0)//不修改,返回主菜單
{return;}
}
void addfromtxtfile(AddrList &addrlist)//從正文文件中添加數據到庫表中
{
cout<<"請輸入源文件的文件名(擴展名為txt):";
char filename[80];
cin.get();
cin.getline(filename, 80);
ifstream in;
in.open(filename, ios::in|ios::nocreate);
if(!in)
{
cout<<"無法打開源文件"< system("pause"); return;
}
int n;
in>>n; cout<<"正在添加"< char name[10], op[15], hp[15], mp[15], em[20];
Node *p;
while(in>>name>>op>>hp>>mp>>em)
{
p=new Node(name, op, hp, mp, em);
addrlist.AddSort(p);
}
in.close();
cout<<"記錄從正文文件添加成功!"< system("pause");
}
void writetotxtfile(AddrList &addrlist)//將庫表中的數據導出到正文文件
{
cout<<"請輸入目標文件的文件名(擴展名為txt):";
char filename[80];
cin.get();
cin.getline(filename, 80);
ofstream out;
out.open(filename, ios::out|ios::noreplace);
if(!out) {cout<<"創建文件失敗!"< else
{
Node *p;
p=addrlist.GetHeadPtr();
while(p)
{
out<Name<<' '<OfficePhone<<"(O) "< <HomePhone<<"(H) "<MobilePhone<<"(M) "<EMail< p=p->Next;
}
out.close();
cout<<"成功導出正文文件!"< }
}
void sort(AddrList &addrlist)//排序庫表
{
if(addrlist.GetHeadPtr()==NULL)
{cout<<"鏈表中沒有記錄可排序!"< if(addrlist.GetTag()==1)
{
cout<<"當前排序關鍵字為姓名,是否將其改為辦公室電話?[y/n]";
char t; cin>>t;
if(t=='y') {addrlist.SetTag(2); addrlist.Sort(2);}
else return;
}
else
{
cout<<"當前排序關鍵字為辦公室電話,是否將其改為姓名?[y/n]";
char t; cin>>t;
if(t=='y') {addrlist.SetTag(1); addrlist.Sort(1);}
else return;
}
cout<<"排序完成!"<}
void quit(AddrList &addrlist)//退出系統,內部做結尾工作
{addrlist.WriteToFile("addrlist.dat"); system("pause"); exit(0);}
void main()//主函數
{
int choice=0, state;
AddrList addrlist;
addrlist.CreateList("addrlist.dat");//從二進制文件中讀入數據,
//構建鏈表
while(choice!=9)//循環菜單處理
{
system("cls");
DisplayMenu();//顯示主菜單
cin>>choice;
state=cin.rdstate();
while(state||choice<=0||choice>9)// 處理非法輸入,如輸入一個字符
{
cout<<"請重新輸入選擇:";
if(state)
{ char str[80]; cin.clear(); cin.getline(str,80); }
cin>>choice;
state=cin.rdstate();
}
switch(choice)
{
case 1: add(addrlist); break;
case 2: del(addrlist); break;
case 3: showall(addrlist); break;
case 4: query(addrlist); break;
case 5: modify(addrlist); break;
case 6: addfromtxtfile(addrlist); break;
case 7: writetotxtfile(addrlist); break;
case 8: sort(addrlist); break;
case 9: quit(addrlist); break;
default : ;
}
}
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -