通讯录系统课程设计——链表实现——c语言
生活随笔
收集整理的這篇文章主要介紹了
通讯录系统课程设计——链表实现——c语言
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
流程圖
概要設計
選擇單鏈表來完成所有操作,便于插入和刪除,不利于排序。
共11個模塊,分別是主函數模塊實現操作指令和10個子函數模塊,分別是主菜單界面、新建聯系人、瀏覽所有聯系人、修改聯系人信息、刪除聯系人、查找聯系人信息、插入聯系人、保存聯系人信息(寫入文件)、讀取文件信息、對所有聯系人按照姓名進行字典序排序。
詳細設計
??????定義了一個結構體類型PHONE變量,內部有五個字符數組和一個整型變量分別存放——name(姓名)、home(籍貫)、phone1(電話號碼1)、phone2(電話號碼2)、email(電子郵箱)、sign(防止重名的標記,只作用于相互重名的人),還有一個PHONE類型的指針作為next域形成鏈表。此外還有一個全局變量PHONE類型的指針head作為鏈表的頭指針。
2.1 新建聯系人
??????執行這個模塊的前提是沒有檢測到“通訊錄”這個文件,那么需要進行新建通訊錄,實際實現就是尾插法創建鏈表,唯一需要注意的是如何停止輸入返回操作指令界面,這里才用在輸入姓名欄那里輸入“over”來結束新建通訊錄操作,同時會提示操作者進行保存錄入文件。
2.2 瀏覽所有聯系人
?????? 這個模塊的作用主要是隨時能夠查看所有聯系人的信息,在每一次操作指令完成后,調用這個模塊就可以很清晰的看到變化,具體實現只需要利用之前設定的頭指針傳進來一個副本,然后遍歷一遍循環輸出即可,利用\t和\n調一下格式就行。
2.3 修改聯系人信息
??????顧名思義這個模塊是用于修改指定聯系人的某個信息,操作者輸入要修改的人的姓名和序號后,通過遍歷鏈表和strcmp函數,找到指定聯系人之后讓操作者輸入操作指令來表示自己要修改哪一項信息,然后輸入修改后的信息即可。
2.4 查找聯系人信息
??????這個模塊用于查找指定的聯系人信息,這里分為按姓名查找和按姓氏查找,查找本身的運作原理都一樣,遍歷鏈表,利用strcmp函數比較,輸出所有滿足該姓名或該姓氏的人的信息即可,唯一要注意的是在按照姓氏查找時可能會輸入單姓也可能會輸入復姓,所以這里要加個判斷,判斷完后的操作分支都大同小異,如果查找不到那么就輸出查無此人,。
2.5 刪除聯系人
??????這個模塊用于刪除某個指定聯系人的所有信息,在操作者輸入完姓名后,遍歷整個鏈表,利用strcmp函數輸出所有滿足該條件的人,然后再讓操作者輸入序號,即刪除哪個該姓名的人,之后只需執行單鏈表的基本刪除操作模板即可,如果沒有找到操作者輸入的人,那么輸出查無此人。
2.6 添加聯系人
??????這個模塊用于添加聯系人信息,在讓操作者輸入完要添加的聯系人的所有信息后,會有一個很重要的防重名操作,更新要插入的人的序號sign,在插入指定位置前,先定義一個整型變量max賦初值為0,然后把鏈表遍歷一遍,將目前與他重名的最大值賦值給max,最后將max+1賦值給要插入進來的人序號上,保證了重名的存在。之后會有三個選項——首位置插入、尾位置插入和指定姓名前插入,分別對應鏈表插入的兩個特例和一個一般,與之不同的時,指定姓名插入也包含了首位置和尾位置,所以在這個操作內部還需要再分支實現,如果沒有找到操作者輸入的姓名那么便輸出查無此人。
2.7 保存聯系人
??????這個模塊的作用是將信息寫入文件保存,利用FILE創建一個文件指針,然后通過fopen的只寫方式打開,如果打不開可能是內存不夠等原因無法創建文件(一般沒這種情況),打開后遍歷鏈表利用fprintf寫入所有信息即可,\t和\n用于調整格式,最后用fclose關閉文件。
2.8 讀取聯系人
??????這個模塊在主菜單上并沒有顯示出來,他在剛開始便執行了,先通過fopen的只讀方式打開,如果打不開就代表不存在“通訊錄這個文件”,此時便提示操作者要新建聯系人。若能打開便先利用feof遍歷文件,然后利用fscanf讀取信息,尾插法建立單鏈表和新建過程大同小異。
2.9 對所有聯系人按名字進行字典序排序
??????這里的名字可以是中文也可以是英文,中文切換到GB 2312簡體中文編碼方式便一樣可以通過strcmp函數進行比較,才用的排序算法是冒泡排序,因為是單鏈表,無法采用更高級的排序算法,唯一一個需要注意點的是,在交換過程中只交換數據域,由于在數據定義過程中沒有單獨定義數據域的結構體,所以需要一個個交換,不能整體交換結構體的值,否則next域就亂了,如果存在同名現象,采取序號更小的放到前面。
2.10 主菜單界面
??????利用多個printf打造了一個主菜單函數,將它單獨作為一個模塊是因為,如果操作者執行的操作比較多可以輸入相應的操作指令再顯示菜單,而不是每次都劃上去看。
2.11 主函數
?????? 主函數首先執行了一個color函數來調整背景色和字體顏色,通過查找資料知道,0是底黑色,E是字體淡黃色。然后調用主菜單模塊與讀取聯系人模塊,然后定義一個整型變量a,通過while循環不斷輸入a然后利用swtich檢測a,來執行不同的操作。
c代碼:
#include<stdio.h> #include<string.h> #include<malloc.h> #include<stdlib.h> #include<windows.h> #define len sizeof(phone) typedef struct PHONE {char name[20];char home[40];char phone1[20];char phone2[20];char email[25];int sign;struct PHONE *next; }phone; phone *head; void mainmenuface() {printf("歡迎來到我們的通訊錄系統!!!\n");printf("★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆\n");printf("☆********************************************************************★\n");printf("★ 通訊錄管理系統 ☆\n");printf("☆ ★\n");printf("★ 1.新建聯系人信息 2.瀏覽所有聯系人 ☆\n");printf("☆ ★\n");printf("★ 3.修改聯系人信息 4.查找聯系人信息 ☆\n");printf("☆ ★\n");printf("★ 5.保存聯系人信息 6.添加聯系人信息 ☆\n");printf("☆ ★\n");printf("★ 7.刪除聯系人信息 8.返回主菜單 ☆\n");printf("☆ ★\n");printf("☆ 9.對通訊錄名單按字典序排序 ★\n");printf("☆********************************************************************★\n");printf("★ 輸入0退出系統 ☆\n");printf("★ 進行完任意一組操作后記得按5保存 ☆\n");printf("☆ ------------------------------------------- ★\n"); }//主菜單 void show_one(phone *p) {printf("姓名:%s\t\t",p->name);printf("序號:%d\n",p->sign);printf("籍貫:%s\t",p->home);printf("電話號碼1:%s\t",p->phone1);printf("電話號碼2:%s\t",p->phone2);printf("電子郵箱:%s\n",p->email); } phone *Lookdata(phone *p1) {phone *p2;p2=head;printf("\n\t\t\t☆☆☆顯示數據☆☆☆\n");printf("----------------------------------------------------------------------\n");while(p2!=NULL){printf("姓名:%s\t\t",p2->name);printf("序號:%d\n",p2->sign);printf("籍貫:%s\t",p2->home);printf("電話號碼1:%s\t",p2->phone1);printf("電話號碼2:%s\t",p2->phone2);printf("電子郵箱:%s\t",p2->email);printf("\n\n");printf("----------------------------------------------------------------------\n");p2=p2->next;}return p2; } phone *Inputdata(){phone*p1,*p2;int flag=1;int k=1,i=1;p1=p2=(phone*)malloc(len);head=NULL;printf("\n\t\t\t☆☆☆新建聯系人信息☆☆☆\n");if(p1!=NULL){head=p1;while(flag){printf("----------------------------------------------------------------------\n");printf("請輸入要錄入聯系人的姓名(姓名一欄中輸入over結束建立聯系人操作并返回操作指令)\n");scanf("%s",p1->name);if(strcmp(p1->name,"over")!=0) {printf("請輸入要錄入聯系人的序號(防重名,做標記)\n");scanf("%d",&p1->sign);getchar();printf("請輸入要錄入聯系人的籍貫\n");scanf("%s",p1->home);printf("請輸入要錄入聯系人的電話1(沒有可輸入“無”)\n");scanf("%s",p1->phone1);printf("請輸入要錄入聯系人的電話2(沒有可輸入“無”)\n");scanf("%s",p1->phone2);printf("請輸入要錄入聯系人的電子郵箱(沒有可輸入“無”)\n");scanf("%s",p1->email);p2->next=p1;p2=p1;p1=(phone*)malloc(len);p1->next=NULL;printf("----------------------------------------------------------------------\n");}else {flag=0;p1->next=NULL;free(p1);printf("-----------------輸入成功!退出時勿忘輸入5保存信息!------------------\n");printf("----------------------------------------------------------------------\n");}}}return (head); } void readfile(){FILE *fp;phone *p1,*p2,*p3;p1=p2=(phone*)malloc(len); int flag=1;head=NULL;if((fp=fopen("通訊錄","r"))==NULL){printf("未建立通訊錄,請輸入1新建聯系人!\n");}else {if(p1!=NULL)head=p1;while(1) {if(!feof(fp)) {fscanf(fp,"%s%d%s%s%s%s",p1->name,&p1->sign,p1->home,p1->phone1,p1->phone2,p1->email);p2->next=p1;p3=p2;p2=p1; p1=(phone*)malloc(len);}else {p3->next=NULL;break;}}}fclose(fp); } void Seek(phone *p2) {char name[20];char ch1[10], ch2[10];memset(ch1,'\0',sizeof(ch1));memset(ch2,'\0',sizeof(ch2));int b;int n;printf("\n\t\t\t☆☆☆查找數據☆☆☆\n");printf("----------------------------------------------------------------------\n");printf("---------------------------按姓名請輸入1:-----------------------------\n");printf("---------------------------按姓氏請輸入2:-----------------------------\n");printf("請輸入您的選擇:");scanf("%d",&n);getchar();printf("請輸入需要查找的姓名:");switch(n) {case 1:b=0;scanf("%s",name);while(p2!=NULL) {if(strcmp(name,p2->name)==0) {printf("你要找到的數據\n");printf("姓名:%s\t\t",p2->name);printf("序號:%d\n",p2->sign);printf("籍貫:%s\t",p2->home);printf("電話號碼1:%s\t",p2->phone1);printf("電話號碼2:%s\t",p2->phone2);printf("電子郵箱:%s\n",p2->email);printf("----------------------------------------------------------------------\n");b=1;}p2=p2->next;}if(b==0) {printf("\n--------------------您要查找的人不存在!--------------------------------\n");}break;case 2:b=0;printf("請輸入姓:");scanf("%s",ch1);while(p2!=NULL){if(strlen(ch1)==2){ strncpy(ch2,p2->name,2);if(strcmp(ch1,ch2)==0) {printf("你要找到的數據\n");printf("姓名:%s\t\t",p2->name);printf("序號:%d\n",p2->sign);printf("籍貫:%s\t",p2->home);printf("電話號碼1:%s\t",p2->phone1);printf("電話號碼2:%s\t",p2->phone2);printf("電子郵箱:%s\n",p2->email);printf("----------------------------------------------------------------------\n");b=1;}p2=p2->next;}if(strlen(ch1)==4){strncpy(ch2,p2->name,4);if(strcmp(ch1,ch2)==0) {printf("你要找到的數據\n");printf("姓名:%s\t\t",p2->name);printf("序號:%d\n",p2->sign);printf("籍貫:%s\t",p2->home);printf("電話號碼1:%s\t",p2->phone1);printf("電話號碼2:%s\t",p2->phone2);printf("電子郵箱:%s\n",p2->email);printf("----------------------------------------------------------------------\n");b=1;}p2=p2->next;} }if(b==0) {printf("\n--------------------您要查找的姓不存在!--------------------------------\n");}} } void Keepdata(phone*p2) {FILE *fp;printf("\n\t\t\t☆☆☆保存數據☆☆☆\n");printf("----------------------------------------------------------------------\n");if((fp=fopen("通訊錄","w"))==NULL) {printf("cannot open this file\n");exit(0);}while(p2!=NULL) {fprintf(fp,"%s\t",p2->name);fprintf(fp,"%d\t",p2->sign);fprintf(fp,"%s\t",p2->home);fprintf(fp,"%s\t",p2->phone1);fprintf(fp,"%s\t",p2->phone2);fprintf(fp,"%s\t",p2->email);p2=p2->next;fputc('\n',fp);}printf("\n------------------------------保存成功!-----------------------------\n");printf("---------------------------------------------------------------------\n");fclose(fp); } void Changedata(phone *p) {char name[20];int k, flag=1,a;printf("\n\t\t\t☆☆☆修改數據☆☆☆\n");printf("----------------------------------------------------------------------\n");printf("---------------------請輸入需要修改的聯系人姓名:---------------------\n");scanf("%s",name);printf("---------------------請輸入需要修改的聯系人序號:---------------------\n");scanf("%d",&a); while(p!=NULL) {if(strcmp(p->name,name)==0&&a==(p->sign)){show_one(p);flag=0;printf("\n------------------請選擇要修改的信息:---------------------------\n");printf("+------------------------------------------------+\n");printf("| |\n");printf("| 1.姓名 4.手機2 |\n");printf("| |\n");printf("| 2.戶籍 5.電子郵箱 |\n");printf("| |\n");printf("| 3.手機1 |\n");printf("| |\n");printf("+------------------------------------------------+\n");scanf("%d",&k);switch(k) {case 1: printf("-------------------輸入修改后的姓名:------------------\n");scanf("%s",p->name);break;case 2: printf("-------------------輸入修改后的戶籍:------------------\n");scanf("%s",p->home);break;case 3: printf("-------------------輸入修改后的手機1:-----------------\n");scanf("%s",p->phone1);break;case 4: printf("-------------------輸入修改后的手機2:-----------------\n");scanf("%s",p->phone2);break;case 5: printf("--------------------輸入修改后的郵箱:------------------\n");scanf("%s",p->email);break;}printf("-----------------------修改成功!-------------------------------------\n");printf("----------------------------------------------------------------------\n");break;}else p=p->next;}if(flag)printf("------------------------查無此人!------------------------------------\n");printf("----------------------------------------------------------------------\n"); } void deletedata() {phone *p1,*p2;phone *p3;char name[20];int n,k=1;printf("\n\t\t\t☆☆☆刪除數據☆☆☆\n");printf("----------------------------------------------------------------------\n");printf("輸入您想刪除的聯系人姓名:\n");scanf("%s",name);p1=head;if(head==NULL) {printf("未建立聯系人信息,通訊錄為空\n");return;}printf("請選擇你要刪除的人:\n");printf("----------------------------------------------------------------------\n");p3=head;while(p3!=NULL) {if(strcmp(name,p3->name)==0) {printf("姓名:%s\t\t",p3->name);printf("序號:%d\n",p3->sign);printf("籍貫:%s\t",p3->home);printf("電話號碼1:%s\t",p3->phone1);printf("電話號碼2:%s\t",p3->phone2);printf("電子郵箱:%s\n",p3->email);printf("\n\n");k=0;printf("----------------------------------------------------------------------\n");}p3=p3->next;}if(k){printf("查無此人!\n");return;}printf("請輸入您要刪除的人序號:\n");scanf("%d",&n);while(p1!= NULL&&(p1->sign!=n||strcmp(p1->name,name)!=0)) {p2=p1;p1=p1->next;}if(p1==NULL) {printf("查無此人!\n");return;}if(p1!=NULL) {p1=p1->next;p2->next=p1;printf("------------------------------刪除成功!------------------------------\n");return;}printf("----------------------------------------------------------------------\n"); } void input(phone *p1) {printf("姓名:");scanf("%s",&p1->name);printf("籍貫:");scanf("%s",&p1->home);printf("手機號1(沒有可輸入“無”):");scanf("%s",&p1->phone1);printf("手機號2(沒有可輸入“無”):");scanf("%s",&p1->phone2);printf("郵箱(沒有可輸入“無”):");scanf("%s",&p1->email);p1->sign=1; } void Insertdata() {char name2[20];int flag,max;phone *p1,*p2,*p3,*p4;p1=head;p3=(phone*)malloc(len);printf("\n\t\t\t☆☆☆添加聯系人☆☆☆\n");printf("----------------------------------------------------------------------\n");printf("-------------------------請輸入相關的數據:---------------------------\n");input(p3);p4=head;max=0;while(p4!=NULL) {if(strcmp(p3->name,p4->name)==0){if(p4->sign>max)max=p4->sign;}p4=p4->next;}p3->sign=++max;printf("-------------------------請輸入插入的位置:---------------------------\n");printf("+---------------------------------------------------------+\n");printf("| |\n");printf("| 1.首位置插入 |\n");printf("| |\n");printf("| 2.尾位置插入 |\n");printf("| |\n");printf("| 3.指定姓名前插入 |\n");printf("+---------------------------------------------------------+\n");scanf("%d",&flag);switch(flag){case 1:p3->next=p1;head=p3;break;case 2:p2=head;while(p2->next!=NULL) {p2=p2->next;}p2->next=p3;p3->next=NULL;break;case 3:printf("請輸入您想插入的姓名前面:\n");scanf("%s",name2);while(p1->next!=NULL&&strcmp(p1->name,name2)!=0){p2=p1;p1=p1->next;}if(p1==head) {p3->next=p1;head=p3;return;}if(p1==NULL) {printf("------------------------------查無此人!---------------------------\n");}else {p3->next=p1;p2->next=p3;}break;}printf("------------------------------插入成功!------------------------------\n");printf("----------------------------------------------------------------------\n");return; } void Sort(phone *p) {phone *p1=p;phone *p2=p;char tname[20];char thome[40];char tphone1[20];char tphone2[20];char temail[25];int tsign;if(p==NULL||p->next==NULL){return;}else{while(p1!=NULL){p2=p1;while(p2!=NULL){if(strcmp(p1->name,p2->name)>0){strcpy(tname,p1->name);strcpy(p1->name,p2->name);strcpy(p2->name,tname);strcpy(thome,p1->home);strcpy(p1->home,p2->home);strcpy(p2->home,thome);strcpy(tphone1,p1->phone1);strcpy(p1->phone1,p2->phone1);strcpy(p2->phone1,tphone1);strcpy(tphone2,p1->phone2);strcpy(p1->phone2,p2->phone2);strcpy(p2->phone2,tphone2);strcpy(temail,p1->email);strcpy(p1->email,p2->email);strcpy(p2->email,temail);tsign=p1->sign;p1->sign=p2->sign;p2->sign=tsign;}else if(strcmp(p1->name,p2->name)==0){if(p1->sign>p2->sign){strcpy(tname,p1->name);strcpy(p1->name,p2->name);strcpy(p2->name,tname);strcpy(thome,p1->home);strcpy(p1->home,p2->home);strcpy(p2->home,thome);strcpy(tphone1,p1->phone1);strcpy(p1->phone1,p2->phone1);strcpy(p2->phone1,tphone1);strcpy(tphone2,p1->phone2);strcpy(p1->phone2,p2->phone2);strcpy(p2->phone2,tphone2);strcpy(temail,p1->email);strcpy(p1->email,p2->email);strcpy(p2->email,temail);tsign=p1->sign;p1->sign=p2->sign;p2->sign=tsign;}}p2=p2->next;}p1=p1->next;}}printf("------------------------------排序完成!------------------------------\n"); } int main() {int a;system("color 0E"); mainmenuface();readfile();while(1){printf("-------------------請選擇您的操作:----------------------\n");scanf("%d",&a);if(a>=0&&a<=10){switch(a){case 0:exit(1);break;case 1:Inputdata();break;case 2:Lookdata(head);break;case 3:Changedata(head);break;case 4:Seek(head);break;case 5:Keepdata(head);break;case 6:Insertdata();break;case 7:deletedata();break;case 8:mainmenuface();break;case 9:Sort(head);break;}}else {printf("---------------選擇的操作不正確!請重新輸入:------------------\n");}}return 0; }備注:只有一個聯系人的時候不要執行瀏覽所有聯系人,會死循環,就這一個bug,QAQ。
總結
以上是生活随笔為你收集整理的通讯录系统课程设计——链表实现——c语言的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 完美解决win7作为虚拟机无法复制粘贴共
- 下一篇: 各行业软件