【C++课程设计】基于单向链表的通讯录管理程序
本文目錄
- 通訊錄效果圖
- 問(wèn)題描述
- 任務(wù)要求
- 設(shè)計(jì)思想
- 功能模塊
- 1,數(shù)據(jù)存儲(chǔ)
- 2,交互界面
- 3,主類功能匹配與整合
- 程序流程圖
- 源碼實(shí)現(xiàn)
- 【1】Link.h
- 【2】MYGUI.h
- 【3】通訊錄.cpp
- 不足
- 課程設(shè)計(jì)報(bào)告與源碼獲取
通訊錄效果圖
問(wèn)題描述
該設(shè)計(jì)采用菜單作為應(yīng)用程序的主要界面,用控制語(yǔ)句來(lái)改變程序執(zhí)行的順序,控制語(yǔ)句是實(shí)現(xiàn)結(jié)構(gòu)化程序設(shè)計(jì)的基礎(chǔ)。該設(shè)計(jì)的任務(wù)是利用一個(gè)簡(jiǎn)單實(shí)用的菜單,通過(guò)菜單單項(xiàng)進(jìn)行選擇,實(shí)現(xiàn)和完成通訊錄管理中常用的幾個(gè)不同的功能。通訊者所包含信息請(qǐng)自行設(shè)定
任務(wù)要求
菜單內(nèi)容:
(0)通訊錄鏈表的建立
(1)通訊者結(jié)點(diǎn)的插入
(2)通訊者結(jié)點(diǎn)的查詢
(3)通訊者結(jié)點(diǎn)的刪除
(4)通訊錄鏈表的輸出
(5)退出管理系統(tǒng)
設(shè)計(jì)要求:
使用0-5來(lái)選擇菜單項(xiàng),可擴(kuò)展功能。
功能函數(shù)設(shè)計(jì)
5個(gè)不同功能的算法實(shí)現(xiàn)編程題,目的是練習(xí)利用鏈表結(jié)構(gòu)來(lái)解決實(shí)際應(yīng)用問(wèn)題的能力,進(jìn)一步理解和熟悉線形表的鏈?zhǔn)酱鎯?chǔ)結(jié)構(gòu)
設(shè)計(jì)思想
將數(shù)據(jù)存儲(chǔ)的鏈表,用戶交互界面,核心測(cè)試類分成三大模塊。鏈表,界面作為頭文件,引入到測(cè)試類中,實(shí)現(xiàn)功能的分塊整合。不同模塊中有具體的實(shí)現(xiàn),通過(guò)接口類,暴露實(shí)現(xiàn)方法名稱,隱藏實(shí)現(xiàn)細(xì)節(jié)。
功能模塊
1,數(shù)據(jù)存儲(chǔ)
以簡(jiǎn)單單向列表的形式來(lái)存儲(chǔ)數(shù)據(jù),鏈表實(shí)現(xiàn)類繼承接口類,并實(shí)現(xiàn)其中的方法。
2,交互界面
通過(guò)字符畫的形式構(gòu)建交互界面,并將繪制界面的各個(gè)方法,封裝入界面繪制工具類中,定義在“MYGUI.h”的頭文件中。
3,主類功能匹配與整合
將數(shù)據(jù)存儲(chǔ)模塊“Link.h”和交互界面“MYGUI.h”載入主類中,通過(guò)子類的工具類,根據(jù)用戶的不同操作匹配調(diào)用各個(gè)頭文件中的方法,并整合流程與方法。
通訊錄程序模塊圖
程序流程圖
程序流程圖源碼實(shí)現(xiàn)
【1】Link.h
#include<iostream> #include<string> #include<fstream> using namespace std; static int counts=0;//鏈數(shù) static int foot;//索引 class ILink{//接口類,暴露方法,隱藏細(xì)節(jié) protected:virtual void add(string data)=0;virtual int count()=0;virtual bool isEmpty()=0;virtual string get(int index)=0;virtual void set(int index)=0;virtual void toArray()=0;virtual bool contains(string data)=0;virtual void remove(int index)=0;virtual void clean()=0;virtual void fileOut(char* path)=0;virtual void fileIn(char* path)=0; }; class Node{//結(jié)點(diǎn)類 public:string data;//結(jié)點(diǎn)數(shù)據(jù) Node *next=NULL;//保留下一節(jié)點(diǎn) Node(string data){this->data=data;}//Node類對(duì)外支持的方法,主要使用了遞歸 void addNode(Node* newNode){if(this->next==NULL){this->next=newNode;}else{this->next->addNode(newNode);}}void toArrayNode(){cout<<"["<<foot++<<"]"<<this->data<<endl;if(this->next!=NULL){this->next->toArrayNode();}}string getNode(int index){if(foot++==index){return this->data;}else{return this->next->getNode(index);}}void setNode(int index,string data){if(foot++==index){this->data=data;}else{this->next->setNode(index,data);}}bool containsNode(string data){if(this->data==data){return 1;}else if(this->next==NULL){return 0;}else{return this->next->containsNode(data);}}void removeNode(Node* previous,int index){//一定要接受指針,進(jìn)行地址傳遞,不能進(jìn)行值傳遞 if(foot++==index){previous->next=this->next;}else if(this->next!=NULL){this->next->removeNode(this,index);}}void fileOutNode(char* path)throw (int){ofstream file;file.open(path,ios::app);if(!file){throw 0;return ;}file<<this->data<<endl;if(this->next!=NULL){this->next->fileOutNode(path);}else{file.close();//關(guān)閉文件流 }}}; class Link:public ILink{private:Node *root=NULL;//初始化根節(jié)點(diǎn) public:~Link(){delete root;}//Link類對(duì)外支持的方法 void add(string data){//add的兩種形式:向根節(jié)點(diǎn)添加,向子節(jié)點(diǎn)添加 Node* newNode=new Node(data);if(this->root==NULL){ this->root=newNode;}else{this->root->addNode(newNode);}counts++;//鏈數(shù)加一 } int count(){return counts;}bool isEmpty(){return counts==0;}void toArray(){if(this->isEmpty()){cout<<"鏈表中沒(méi)有數(shù)據(jù)"<<endl;}foot=1;root->toArrayNode();}string get(int index) throw (int){if(index>counts|index<=0){//兩個(gè)判斷都要進(jìn)行,所以不用短路或“||” throw 0;//索引無(wú)效 return "ERROR";}foot=1;//初始化索引 return this->root->getNode(index);}void set(int index)throw (int){if(index>counts|index<=0){//兩個(gè)判斷都要進(jìn)行,所以不用短路或“||” throw 0;//索引無(wú)效 return;}string str[4];cout<<"通訊者 [姓名]:";cin>>str[0];cout<<"通訊者 [電話]:";cin>>str[1];cout<<"通訊者 [QQ]:";cin>>str[2];str[3]="[姓名]:"+str[0]+" [電話]:"+str[1]+" [QQ]:"+str[2];foot=1;//初始化索引 this->root->setNode(index,str[4]);}bool contains(string data){return this->root->containsNode(data);}void remove(int index) throw (int){//remove的兩種形式:輸出根節(jié)點(diǎn),刪除子節(jié)點(diǎn) if(index>counts|index<=0){//兩個(gè)判斷都要進(jìn)行,所以不用短路或“||” throw 0;//索引無(wú)效 return;}if(index==1){this->root=this->root->next;counts--;//鏈數(shù)減一 }else{foot=1;this->root->removeNode(this->root,index); counts--;}}void fileOut(char* path){//鏈表導(dǎo)出 if(this->isEmpty()){cout<<"鏈表中沒(méi)有數(shù)據(jù)"<<endl;}root->fileOutNode(path);} void fileIn(char* path)throw(int){//文件導(dǎo)入 ifstream file(path);string data;if(!file){throw 0;return;}getline(file,data);//整行導(dǎo)入 while(!file.eof()&&data!=""){//判斷文件結(jié)尾 this->add(data);getline(file,data);//整行導(dǎo)入 }file.close(); }void clean(){//清空根節(jié)點(diǎn) this->root=NULL;counts=0;} };【2】MYGUI.h
#include<iostream> #include<string> #include<cstdlib> using namespace std; class MYGUI{//繪制界面工具類 public:static void start(){//設(shè)置窗口大小 system("mode con cols=55 lines=36");}static void menu(){//畫菜單 cout<<" +-----------------------------------------------------+\n";cout<<" | |\n";cout<<" | 0 000000 0 00000000 |\n";cout<<" | 0 0 0 0 00000 0 |\n";cout<<" | 00 0 0 0000000 |\n";cout<<" | 0000000 0 0 0 |\n";cout<<" | 00 0 0 0 000 0 0 00000000000 |\n";cout<<" | 0 0000000 0 00000 0 |\n";cout<<" | 0 0 0 0 0 0 0 0 0 0 |\n";cout<<" | 0 0000000 0 0 0 0 000 0 |\n";cout<<" | 0 0 0 0 0 0 0 0 0 0 |\n";cout<<" | 0 0 0 00 00 0 0 0 0 0 0 |\n";cout<<" | 0 0 0 00 00 0 00 |\n";cout<<" | 0 000000000 0 0 00 |\n";cout<<" | |\n";cout<<" |-----------------------------------------------------|\n";cout<<" | |\n";cout<<" | [SoftMenu] |\n";cout<<" | |\n";cout<<" | (0) 通訊錄鏈表的建立 |\n";cout<<" | |\n";cout<<" | (1) 通訊者鏈表的導(dǎo)入 |\n";cout<<" | |\n";cout<<" | (2) 通訊者結(jié)點(diǎn)的插入 |\n";cout<<" | |\n";cout<<" | (3) 通訊者結(jié)點(diǎn)的查詢 |\n";cout<<" | |\n";cout<<" | (4) 通訊者結(jié)點(diǎn)的修改 |\n";cout<<" | |\n";cout<<" | (5) 通訊者結(jié)點(diǎn)的刪除 |\n";cout<<" | |\n";cout<<" | (6) 通訊錄鏈表的清空 |\n";cout<<" | |\n";cout<<" | (7) 通訊錄鏈表的打印 |\n";cout<<" | |\n";cout<<" | (8) 通訊錄鏈表的導(dǎo)出 |\n";cout<<" | |\n";cout<<" | (9) 退出管理系統(tǒng) |\n";cout<<" | |\n";cout<<" | |\n";cout<<" +-----------------------------------------------------+\n"; cout<<"【請(qǐng)輸入功能選項(xiàng)】:"<<flush;//flush用于刷新此處的緩沖區(qū),防止輸入數(shù)據(jù)延滯 }static void tip(string tip){//畫提示信息cout<<endl;cout<<" +-----------------"<<tip<<"----------------+\n";cout<<" | |\n";} static void tipMenu(){cout<<" | |\n";cout<<" +-----------------------------------------------------+\n";cout<<" |(0)創(chuàng)建鏈表 (1)導(dǎo)入鏈表 (2)插入結(jié)點(diǎn) (3)查詢結(jié)點(diǎn)|\n";cout<<" |(4)修改結(jié)點(diǎn) (5)刪除結(jié)點(diǎn) (6)清空鏈表 (7)打印鏈表|\n";cout<<" |(8)導(dǎo)出鏈表 (9)退出系統(tǒng) |\n";cout<<" +-----------------------------------------------------+\n";cout<<"【請(qǐng)輸入功能選項(xiàng)】:"; } };【3】通訊錄.cpp
#include<iostream> #include<string> #include"MYGUI.h"//載入界面繪制類 #include"Link.h"//載入鏈表,提供數(shù)據(jù)存儲(chǔ)支持 using namespace std; int option;//輸入選項(xiàng) Link *plink=NULL;//鏈表指針 char input[2];//用戶輸入值,用于驗(yàn)證 class Util{//操作工具類 public://輸入驗(yàn)證,確保數(shù)據(jù)為0-5整數(shù),驗(yàn)證通過(guò)返回解碼后的整數(shù),否則返回-1 static int inputExam(char* input){if(input[0]>='0'&&input[0]<='9'&&input[1]==NULL){return input[0]-48;}return -1;} //輸入選項(xiàng)編號(hào),通過(guò)switch來(lái)匹配各個(gè)選項(xiàng)的功能 static void option(int option){switch(option){case 0:{ //創(chuàng)建鏈表 Util::creatLink();break;} case 1:{//導(dǎo)入文件 Util::importLink();break;}case 2:{//插入結(jié)點(diǎn) Util::insertNode();break;} case 3:{//查詢結(jié)點(diǎn)Util::findNode();break;}case 4:{//修改節(jié)點(diǎn) Util::alterNode();break;} case 5:{//刪除結(jié)點(diǎn)Util::deleteNode();break;}case 6:{//清空鏈表 Util::cleanLink();break;} case 7:{//輸出鏈表 Util::showLink();break;}case 8:{//鏈表導(dǎo)出 Util::exportLink();break;} }}static void creatLink(){MYGUI::tip("(0) 通訊錄鏈表的建立");if(plink!=NULL){char str;cout<<"【已存在通訊錄鏈表,是否重新創(chuàng)建(y/n)】:"<<flush;cin>>str;if(str=='y'){plink->clean(); //并沒(méi)有重新創(chuàng)建新的鏈表,只不過(guò)是將原有鏈表清空了,這樣節(jié)約內(nèi)存開支 cout<<"【創(chuàng)建通訊錄鏈表成功】\n";MYGUI::tipMenu();}else if(str=='n'){MYGUI::tipMenu();}else{cout<<"【輸入錯(cuò)誤,請(qǐng)輸入(y/n)】\n";Util::option(0);}} else{plink=new Link();cout<<"【創(chuàng)建通訊錄鏈表成功】\n";MYGUI::tipMenu();} } static void importLink(){MYGUI::tip("(1) 通訊錄鏈表的導(dǎo)入"); if(plink!=NULL){char path[100]; //支持char[100]范圍內(nèi)的路徑 cout<<"【請(qǐng)輸入導(dǎo)入文件路徑名稱(.txt)】:";cin>>path; try{plink->fileIn(path); cout<<"【導(dǎo)入文件成功】\n";MYGUI::tipMenu();}catch(int){cout<<"【文件打開失敗,檢查輸入路徑】\n";MYGUI::tipMenu();}}else{cout<<"【尚未創(chuàng)建通訊者鏈表,請(qǐng)創(chuàng)建】\n";MYGUI::tipMenu();} }static void insertNode(){MYGUI::tip("(2) 通訊者結(jié)點(diǎn)的插入");if(plink!=NULL){string str[4];//存儲(chǔ)輸入的數(shù)據(jù) cout<<"【插入第"<<plink->count()+1<<"個(gè)通訊者信息】\n";cout<<"通訊者 [姓名]:";cin>>str[0];cout<<"通訊者 [電話]:";cin>>str[1];cout<<"通訊者 [QQ]:";cin>>str[2];str[3]="[姓名]:"+str[0]+" [電話]:"+str[1]+" [QQ]:"+str[2];plink->add(str[3]);cout<<"【第"<<plink->count()<<"個(gè)通訊者信息錄入完成】\n";MYGUI::tipMenu(); }else{cout<<"【尚未創(chuàng)建通訊者鏈表,請(qǐng)創(chuàng)建】\n";MYGUI::tipMenu();} }static void findNode(){MYGUI::tip("(3) 通訊者結(jié)點(diǎn)的查詢"); if(plink!=NULL){if(plink->isEmpty()){cout<<"【尚未錄入通訊者信息,請(qǐng)錄入】\n";MYGUI::tipMenu();}else{int index;//輸入的查詢索引 string data;//存儲(chǔ)查詢得到的信息 cout<<"【請(qǐng)輸入要查詢通訊者的編號(hào)】:";cin>>index;try{//異常處理 data=plink->get(index);cout<<"【查詢結(jié)果】\n";cout<<data<<endl;MYGUI::tipMenu();}catch(int){cout<<"【查詢失敗,檢查編號(hào)】\n";MYGUI::tipMenu();} }}else{cout<<"【尚未創(chuàng)建通訊者鏈表,請(qǐng)創(chuàng)建】\n";MYGUI::tipMenu();} }static void alterNode(){MYGUI::tip("(4) 通訊者結(jié)點(diǎn)的修改"); if(plink!=NULL){if(plink->isEmpty()){cout<<"【尚未錄入通訊者信息,請(qǐng)錄入】\n";MYGUI::tipMenu();}else{int index;cout<<"【請(qǐng)輸入需要修改通訊者的編號(hào)】:";cin>>index;try{plink->set(index); cout<<"【修改成功】\n";MYGUI::tipMenu();}catch(int){cout<<"【修改失敗,檢查編號(hào)】\n";MYGUI::tipMenu();}}}else{cout<<"【尚未創(chuàng)建通訊者鏈表,請(qǐng)創(chuàng)建】\n";MYGUI::tipMenu();}} static void deleteNode(){MYGUI::tip("(5) 通訊者結(jié)點(diǎn)的刪除"); if(plink!=NULL){if(plink->isEmpty()){cout<<"【尚未錄入通訊者信息,請(qǐng)錄入】\n";MYGUI::tipMenu();}else{int index;cout<<"【請(qǐng)輸入需要?jiǎng)h除通訊者的編號(hào)】:";cin>>index; try{//異常處理 plink->remove(index);cout<<"【刪除成功】\n";MYGUI::tipMenu();}catch(int){cout<<"【刪除失敗,檢查編號(hào)】\n";MYGUI::tipMenu();}}}else{cout<<"【尚未創(chuàng)建通訊者鏈表,請(qǐng)創(chuàng)建】\n";MYGUI::tipMenu();} }static void cleanLink(){MYGUI::tip("(6) 通訊者鏈表的清空"); if(plink!=NULL){if(plink->isEmpty()){cout<<"【空鏈表,無(wú)需清空】\n";MYGUI::tipMenu();}else{plink->clean();cout<<"【清空成功】\n";MYGUI::tipMenu();} } else{cout<<"【未創(chuàng)建通訊者鏈表,請(qǐng)創(chuàng)建】\n";MYGUI::tipMenu();}}static void showLink(){MYGUI::tip("(7) 通訊錄鏈表的輸出"); if(plink!=NULL){if(plink->isEmpty()){cout<<"【未錄入通訊者信息,請(qǐng)錄入】\n";MYGUI::tipMenu();}else{cout<<"【輸出結(jié)果】\n" ;plink->toArray(); MYGUI::tipMenu();}}else{cout<<"【尚未創(chuàng)建通訊者鏈表,請(qǐng)創(chuàng)建】\n";MYGUI::tipMenu();} }static void exportLink(){MYGUI::tip("(8) 通訊錄鏈表的導(dǎo)出"); if(plink!=NULL){if(plink->isEmpty()){cout<<"【尚未錄入通訊者信息,請(qǐng)錄入】\n";MYGUI::tipMenu();}else{char path[100]; //支持char[100]范圍內(nèi)的路徑 cout<<"【請(qǐng)輸入導(dǎo)出文件路徑名稱(.txt)】:";cin>>path; try{plink->fileOut(path); cout<<"【導(dǎo)出文件成功】\n"; MYGUI::tipMenu();}catch(int){cout<<"【文件打開失敗,檢查輸入路徑】\n";MYGUI::tipMenu(); }}}else{cout<<"【尚未創(chuàng)建通訊者鏈表,請(qǐng)創(chuàng)建】\n";MYGUI::tipMenu();} } };int main(){MYGUI::menu();//畫界面 cin>>input;option=Util::inputExam(input);while(option==-1){cout<<"【輸入錯(cuò)誤,請(qǐng)輸入 0~9 范圍類的整數(shù)】:";input[1]=NULL;//初始化input[1] cin>>input;option=Util::inputExam(input);}while(option!=9){//循環(huán)輸入 Util::option(option);cin>>input;option=Util::inputExam(input);//輸入驗(yàn)證 while(option==-1){cout<<"【輸入錯(cuò)誤,請(qǐng)輸入 0~9 范圍類的整數(shù)】:";input[1]=NULL;//初始化input[1] cin>>input;option=Util::inputExam(input);//輸入驗(yàn)證 }}cout<<"\n【bye~】";//結(jié)束 return 0; }不足
沒(méi)有統(tǒng)一的異常處理類,Link需要使用模板來(lái)增加鏈表存儲(chǔ)數(shù)據(jù)類型,擴(kuò)展鏈表用途。日后有時(shí)間再填。
課程設(shè)計(jì)報(bào)告與源碼獲取
【猛擊此處】
總結(jié)
以上是生活随笔為你收集整理的【C++课程设计】基于单向链表的通讯录管理程序的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 《2021爱分析·中国RPA应用趋势报告
- 下一篇: cad图纸怎么看懂_教你如何快速看懂建筑