通訊錄管理系統C語言課程設計
這是本人之前做的一個課設,程式碼比較繁瑣(由於當時不想花太多時間以致沒有進行壓縮)一些但思路比較清晰
注:給出的程式碼可能由於種種問題複製程式碼出問題,在此給出原始檔:連結:http://pan.baidu.com/s/1pKInR3X 密碼:yv6w
一、 課程設計的目的和要求
目的:在已學C語言的基礎上,編寫一個具有實際功能的程式,掌握實際應用程式開發的基本流程——構思,設計框架,所用知識,程式編寫,編譯測試,程式完成。
要求:編寫一個通訊錄,完成顯示、新增、查詢和修改等操作
二、設計
本次課程設計的通訊錄管理系統,本小組共提供了九種基本的功能:
1. 新增聯絡人
2. 查詢聯絡人
3. 刪除聯絡人
4. 修改聯絡人資訊
5. 輸出聯絡人列表
6. 排序
7. 寫入檔案
8. 讀取檔案
9. 通話記錄
現在對每個功能進行分析:
新增聯絡人:
我們設定的聯絡人資訊是由姓名、手機號、QQ、電子郵箱組成,故對其依次輸入,而且對於不同的資訊物件,我們做出了不同的限定:姓名我們給足了空間(按個人喜好設定聯絡人姓名),手機號我們限定為11位數字字串,QQ號碼限定為10位數字字串,電子郵箱只能有一個@號。另外,對於聯絡人資訊的每一項(這裡除了姓名),只要輸入不符,則重新輸入直到你輸入的格式正確為止。以下以其中某一項為例進行分析。
以手機號碼為例:其中的cala函式用於計算字串的長度,這裡指手機號的長度。
查詢聯絡人:
首先,我們查詢的方式可能不同:有些人想查姓名,而有些人查手機號,有些
人則查QQ號碼。對於每一項,我們輸入想查的資訊項,再通過p=head->next
遍歷整個連結串列,依次進行比對,比對成功便輸出此項的相關資訊,若失敗,則
提示“該聯絡人不存在”。
刪除聯絡人:
刪除聯絡人也很簡單,也就是刪除連結串列中的一項,其思路如以下圖示:
修改聯絡人資訊:
和查詢一樣,首先遍歷找到所輸入的資訊項,再進行修改。
輸出聯絡人列表:
通過head指標直接將連結串列輸出。
排序:
如果想要交換連結串列中兩項的位置,則:
寫入檔案:
通過fp=fopen(filename,"a+")開啟檔案,通過fprintf按所輸入形式往檔案寫入資訊。
讀取檔案:
通過fp=fopen(filename,"a+")開啟檔案,通過fgets獲取檔案中的資訊,並用printf
輸出。
通話記錄:
這裡我們設計了一個模擬通話,用一個隨機數來表示,假如隨機數的值位於連結串列中項數之內,則在相應的檔案中寫入聯絡人資訊,如果位於連結串列項數之外,則在相應檔案中寫入未知聯絡人。
三、編碼
提示:由於程式的提示資訊比較多,同時,為了使得該程式功能更加全面,添加了許多判斷,程式比較繁瑣,程式碼量也比較多。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<conio.h>
#include<time.h>
typedef struct chsystem
{
char name[15];//姓名
char tel[20];//手機
char tecent[15];//qq號碼
char email[20];//郵箱
}cs;//通訊錄結構體
typedef struct pcs
{
cs chat;
pcs* next;
}*ptcs;//通訊錄節點
ptcs head=(ptcs)malloc(sizeof(pcs));
int menu_select()//功能選擇框
{
char c;
do
{
system("cls");
printf("\n\t\t**********通訊錄管理系統**********\n");
printf("\t\t┌-------------------------------┐\n");
printf("\t\t│ 1.新增聯絡人 │\n");
printf("\t\t│ 2.查詢聯絡人 │\n");
printf("\t\t│ 3.刪除聯絡人 │\n");
printf("\t\t│ 4.修改聯絡人資訊 │\n");
printf("\t\t│ 5.輸出聯絡人列表 │\n");
printf("\t\t│ 6.排序 │\n");
printf("\t\t│ 7.寫入檔案 │\n");
printf("\t\t│ 8.讀取檔案 │\n");
printf("\t\t│ 9.通話記錄 │\n");
printf("\t\t│ 0.退出 │\n");
printf("\t\t└-------------------------------┘\n");
printf("\t\t請您選擇(0-9):");
c=getchar();
}while(c<'0'||c>'9');//檢查輸入是否符合規範
return(c-'0');
}
int cala(char *p)//計算字串長度
{
int i,n=0;
for(i=0;p[i]!='\0';i++)n++;
return n;
}
int Addpeo()//新增聯絡人
{
int t,n,a;
char flag='y';
ptcs p=head,q;
while(p->next)p=p->next;
while(flag!='n'&&flag!='N')
{
q=(ptcs)malloc(sizeof(pcs));
p->next=q;
p=q;
q->next=NULL;
printf("\n\t\t請輸入:\n");
printf("\t\t姓名:");//輸入姓名
scanf("\t\t%s",q->chat.name);
printf("\t\t手機號碼:");//輸入手機號
scanf("\t\t%s",q->chat.tel);
do
{
n=0;
if(cala(q->chat.tel)!=11)
{
n=1;
printf("\t\t您輸入的手機號碼格式不存在,請重新輸入:");
scanf("\t\t%s",q->chat.tel);
}
else
{
for(t=0;t<11;t++)
{
if(q->chat.tel[t]<'0'||q->chat.tel[t]>'9')
{
n=1;
printf("\t\t您輸入的手機號碼格式不合理,請重新輸入:");
scanf("\t\t%s",q->chat.tel);
break;
}
}
}
}while(n);
printf("\t\tQQ號:");//輸入QQ號
scanf("\t\t%s",q->chat.tecent);
do
{
n=0;
if(cala(q->chat.tecent)>10)
{
n=1;
printf("\t\t您輸入的QQ號碼格式不存在,請重新輸入:");
scanf("\t\t%s",q->chat.tecent);
}
else
{
for(t=0;t<10;t++)
{
if(q->chat.tecent[t]<'0'||q->chat.tecent[t]>'9')
{
n=1;
printf("\t\t您輸入的QQ號碼格式不合理,請重新輸入:");
scanf("\t\t%s",q->chat.tecent);
break;
}
}
}
}while(n);
printf("\t\t電子郵箱:");//輸入郵箱
scanf("\t\t%s",q->chat.email);
do
{
a=0;
for(t=0;q->chat.email[t]!='\0';t++)
{
if(q->chat.email[t]=='@')
a++;
}
if(a!=1)
{
printf("\t\t輸入的郵箱不合理,請重新輸入:");
scanf("\t\t%s",q->chat.email);
}
}while(a!=1);
printf("\n\t\t是否繼續新增?(Y/N)");
scanf("\t\t%c",&flag);
}
return 0;
}
int watch_over()//查詢聯絡人
{
int m,n;
char flag='y';
ptcs p=head->next;
while(flag!='n'&&flag!='N')
{
printf("\n\t\t*************查詢方式*************\n");
printf("\t\t┌-------------------------------┐\n");
printf("\t\t│ 1.查詢姓名 │\n");
printf("\t\t│ 2.查詢手機號 │\n");
printf("\t\t│ 3.查詢QQ號碼 │\n");
printf("\t\t│ 4.返回 │\n");
printf("\t\t└-------------------------------┘\n");
printf("\n\t\t請選擇查詢方式:");
scanf("\t\t%d",&m);//選擇查詢方式
do
{
n=0;
if(m!=1&&m!=2&&m!=3&&m!=4)
{
n=1;
printf("\t\t您輸入的查詢方式不存在,請重新輸入:");
scanf("\t\t%d",&m);//選擇查詢方式
}
}while(n);
if(!p)
{
printf("\t\t該通訊錄為空!\n");
return 0;
}
if(1==m)
{
char nm[15];
p=head->next;
printf("\t\t請輸入您要查詢的聯絡人:");
scanf("\t\t%s",nm);
while(p!=NULL&&strcmp(p->chat.name,nm)!=0)p=p->next;
if(!p)
{
printf("\t\t您要查詢的聯絡人不存在!\n");
printf("\t\t是否繼續查詢?(Y/N)");
scanf("\t\t%c",&flag);
return 0;
}
printf("\t\t手機號碼:%s\n",p->chat.tel);
printf("\t\tqq號:%s\n",p->chat.tecent);
printf("\t\t電子郵箱:%s\n",p->chat.email);
}
if(2==m)
{
char te[20];
p=head->next;
printf("\t\t請輸入您要查詢的手機號碼:");
scanf("\t\t%s",te);
while(p!=NULL&&strcmp(p->chat.tel,te)!=0)p=p->next;
if(!p)
{
printf("\t\t您要查詢的聯絡人不存在!\n");
printf("\t\t是否繼續查詢?(Y/N)");
scanf("\t\t%c",&flag);
return 0;
}
printf("\t\t姓名:%s\n",p->chat.name);
printf("\t\tqq號:%s\n",p->chat.tecent);
printf("\t\t電子郵箱:%s\n",p->chat.email);
}
if(3==m)
{
char qq[15];
p=head->next;
printf("\t\t請輸入您要查詢的qq號:");
scanf("\t\t%s",qq);
while(p!=NULL&&strcmp(p->chat.tecent,qq)!=0)p=p->next;
if(!p)
{
printf("\t\t您要查詢的聯絡人不存在!\n");
printf("\t\t是否繼續查詢?(Y/N)");
scanf("\t\t%c",&flag);
return 0;
}
printf("\t\t姓名:%s\n",p->chat.name);
printf("\t\t手機號:%s\n",p->chat.tecent);
printf("\t\t電子郵箱:%s\n",p->chat.email);
}
if(4==m)return 0;
printf("\t\t是否繼續查詢?(Y/N)");
scanf("\t\t%c",&flag);
}
return 0;
}
int Delete()//刪除個人資訊
{
char nm[20];
char flag='y';
ptcs p=head->next,bh,pre;
if(!p)
{
printf("\t\t該通訊錄為空!\n");
return 0;
}
while(flag!='n'&&flag!='N')
{
p=head->next;
printf("\t\t請輸入您要刪除的聯絡人姓名:");
scanf("\t\t%s",nm);
while(p!=NULL&&strcmp(p->chat.name,nm)!=0)
{
pre=p;
p=p->next;
}
if(!p)
{
printf("\t\t該聯絡人不存在!\n");
printf("\t\t是否繼續刪除?(Y/N)");
scanf("\t\t%c",&flag);
return 0;
}
bh=p->next;
if(p==head->next)head->next=bh;
else pre->next=bh;
printf("\t\t該聯絡人已刪除!\n");
printf("\t\t是否繼續刪除?(Y/N)");
scanf("\t\t%c",&flag);
}
return 0;
}
int changeall(ptcs p)//修改某一聯絡人的所有資訊
{
int a,n,t;
printf("\t\t姓名:");//輸入姓名
scanf("\t\t%s",p->chat.name);
printf("\t\t手機號碼:");//輸入手機號
scanf("\t\t%s",p->chat.tel);
do
{
n=0;
if(cala(p->chat.tel)!=11)
{
n=1;
printf("\t\t您輸入的手機號碼格式不存在,請重新輸入:");
scanf("\t\t%s",p->chat.tel);
}
else
{
for(t=0;t<11;t++)
{
if(p->chat.tel[t]<'0'||p->chat.tel[t]>'9')
{
n=1;
printf("\t\t您輸入的手機號碼格式不合理,請重新輸入:");
scanf("\t\t%s",p->chat.tel);
break;
}
}
}
}while(n);
printf("\t\tQQ號:");//輸入QQ號
scanf("\t\t%s",p->chat.tecent);
do
{
n=0;
if(cala(p->chat.tecent)!=10)
{
n=1;
printf("\t\t您輸入的QQ號碼格式不存在,請重新輸入:");
scanf("\t\t%s",p->chat.tecent);
}
else
{
for(t=0;t<10;t++)
{
if(p->chat.tecent[t]<'0'||p->chat.tecent[t]>'9')
{
n=1;
printf("\t\t您輸入的QQ號碼格式不合理,請重新輸入:");
scanf("\t\t%s",p->chat.tecent);
break;
}
}
}
}while(n);
printf("\t\t電子郵箱:");//輸入郵箱
scanf("\t\t%s",p->chat.email);
do
{
a=0;
for(t=0;p->chat.email[t]!='\0';t++)
{
if(p->chat.email[t]=='@')
a++;
}
if(a!=1)
{
printf("\t\t輸入的郵箱不合理,請重新輸入:");
scanf("\t\t%s",p->chat.email);
}
}while(a!=1);
return 0;
}
int changetel(ptcs p)//修改手機號內容
{
int n,t;
scanf("\t\t%s",p->chat.tel);
do
{
n=0;
if(cala(p->chat.tel)!=11)
{
n=1;
printf("\t\t您輸入的手機號碼格式不存在,請重新輸入:");
scanf("\t\t%s",p->chat.tel);
}
else
{
for(t=0;t<11;t++)
{
if(p->chat.tel[t]<'0'||p->chat.tel[t]>'9')
{
n=1;
printf("\t\t您輸入的手機號碼格式不合理,請重新輸入:");
scanf("\t\t%s",p->chat.tel);
break;
}
}
}
}while(n);
return 0;
}
int changeQQ(ptcs p)//修改QQ號碼
{
int n,t;
scanf("%s",p->chat.tecent);
do
{
n=0;
if(cala(p->chat.tecent)!=10)
{
n=1;
printf("\t\t您輸入的QQ號碼格式不存在,請重新輸入:");
scanf("\t\t%s",p->chat.tecent);
}
else
{
for(t=0;t<10;t++)
{
if(p->chat.tecent[t]<'0'||p->chat.tecent[t]>'9')
{
n=1;
printf("\t\t您輸入的QQ號碼格式不合理,請重新輸入:");
scanf("\t\t%s",p->chat.tecent);
break;
}
}
}
}while(n);
return 0;
}
int changeEmail(ptcs p)//修改電子郵箱
{
int t,a;
scanf("\t\t%s",p->chat.email);
do
{
a=0;
for(t=0;p->chat.email[t]!='\0';t++)
{
if(p->chat.email[t]=='@')
a++;
}
if(a!=1)
{
printf("\t\t輸入的郵箱不合理,請重新輸入:");
scanf("\t\t%s",p->chat.email);
}
}while(a==1);
return 0;
}
int change()//修改聯絡人資訊
{
char nm[20],flag='y';
int m,n;
ptcs p=head->next;
if(!p)
{
printf("\t\t該通訊錄為空!\n");
return 0;
}
while(flag!='n'&&flag!='N')
{
p=head->next;
printf("\n\t\t*******請輸入您要修改的內容*******\n");
printf("\t\t┌-------------------------------┐\n");
printf("\t\t│ 1.聯絡人 │\n");
printf("\t\t│ 2.手機號碼 │\n");
printf("\t\t│ 3.QQ號 │\n");
printf("\t\t│ 4.電子郵箱 │\n");
printf("\t\t│ 5.返回 │\n");
printf("\t\t└-------------------------------┘\n");
printf("\n\t\t請輸入您要修改的內容:");
scanf("\t\t%d",&m);
do
{
n=0;
if(m!=1&&m!=2&&m!=3&&m!=4&&m!=5)
{
n=1;
printf("\t\t您輸入的修改內容不存在,請重新輸入:");
scanf("\t\t%d",&m);//選擇修改內容
}
}while(n);
if(5==m)return 0;
printf("\t\t請輸入您想修改資訊的聯絡人的姓名:");
scanf("\t\t%s",nm);
while(p!=NULL&&strcmp(p->chat.name,nm)!=0)p=p->next;
if(!p)
{
printf("\t\t該聯絡人不存在!\n");
return 0;
}
if(1==m)
{
printf("\t\t請輸入您的修改:\n");
changeall(p);
}
if(2==m)
{
printf("\t\t請輸入%s的手機號碼:",p->chat.name);
changetel(p);
}
if(3==m)
{
printf("\t\t請輸入%s的QQ號:",p->chat.name);
changeQQ(p);
}
if(4==m)
{
printf("\t\t請輸入%s的電子郵箱:",p->chat.name);
changeEmail(p);
}
printf("\t\t是否繼續修改?(Y/N)");
scanf("\t\t%c",&flag);
}
return 0;
}
int display()//輸出通訊錄列表
{
ptcs p=head->next;
if(!p)
{
printf("\t\t該通訊錄為空!\n");
return 0;
}
printf("\n\t\t******************************通訊錄列表******************************\n");
printf("\t\t姓名\t\t手機號碼\tQQ號碼\t\t電子郵箱\n");
printf("\t\t----------------------------------------------------------------------\n");
while(p)
{
printf("\t\t%-16s%-16s%-16s%-20s\n",p->chat.name,p->chat.tel,p->chat.tecent,p->chat.email);
p=p->next;
printf("\t\t----------------------------------------------------------------------\n");
}
return 0;
}
int cacu(ptcs p)//計算連結串列的長度
{
int n=0;
while(p)
{
p=p->next;
n++;
}
return n;
}
int arrange()//對通訊錄進行排序,這裡本人用冒泡法排序,稍微有些繁瑣
{
int i,n;
ptcs pre=head,p=head->next,k,q;
if(!p)
{
printf("\t\t該通訊錄為空!\n");
return 0;
}
n=cacu(p);
for(i=0;i<n-1;i++)
{
for(p=head->next,pre=head;p->next->next!=NULL;pre=p,p=p->next);
{
k=p->next;
q=k->next;
if(strcmp(p->chat.name,k->chat.name)>0)
{
pre->next=k;
k->next=p;
p->next=q;
p=k;
}
}
}
display();
return 0;
}
int write()//將資料寫入檔案
{
ptcs p=head->next;
FILE* fp;
char filename[30];
if(!p)
{
printf("\t\t該通訊錄為空!");
return 0;
}
printf("\t\t寫入到檔案!\n");
printf("\t\t請輸入所寫入的檔名:");
scanf("\t\t%s",filename);
if((fp=fopen(filename,"a+"))==NULL)
{
printf("\t\t無法開啟檔案!\n");
system("pause");
return 0;
}
fprintf(fp,"******************************通訊錄列表******************************\n");
fprintf(fp,"姓名\t\t手機號碼\tQQ號碼\t\t電子郵箱\n");
fprintf(fp,"----------------------------------------------------------------------\n");
while(p)
{
fprintf(fp,"%-16s%-16s%-16s%-20s\n",p->chat.name,p->chat.tel,p->chat.tecent,p->chat.email);
p=p->next;
fprintf(fp,"----------------------------------------------------------------------\n");
}
fprintf(fp,"\n******************************共%d個聯絡人******************************\n",cacu(head->next));
fclose(fp); //關閉檔案
printf("\t\t寫入成功!\n");
return 0;
}
int read()//讀取檔案
{
char str[100],char filename[30];
FILE* fp;
printf("\t\t讀取檔案!\n");
printf("\t\t請輸入所寫入的檔名:");
scanf("\t\t%s",filename);
if((fp=fopen(filename,"a+"))==NULL)
{
printf("\t\t無法開啟檔案!\n");
system("pause");
return 0;
}
while((fgets(str,100,fp))!=NULL)
{
printf("\t\t%s",str);
}
return 0;
}
int call()//呼叫或被呼叫
{
int n;
ptcs p=head->next;
srand((unsigned) time(NULL)); //用時間做種,每次產生隨機數不一樣
n=rand()%(cacu(p)+5)+1;
return n;
}
int save(int n,char *filename)//儲存通話記
{
FILE* fp;
ptcs p=head->next;
int i=1;
if((fp=fopen(filename,"a+"))==NULL)
{
printf("\t\t通話記錄將失去!\n");
system("pause");
return 0;
}
if(n<=cacu(p))
{
while(i<n)
{
p=p->next;
i++;
}
fprintf(fp,"%-16s%-16s%-16s%-20s\n",p->chat.name,p->chat.tel,p->chat.tecent,p->chat.email);
fprintf(fp,"----------------------------------------------------------------------\n");
}
else fprintf(fp,"未知號碼\n");
fclose(fp); //關閉檔案
return 0;
}
int chat_record()//通話記錄
{
int m,n,i;
char flag='y';
char cal[30]="call.txt",caled[30]="called.txt";
while(flag!='n'&&flag!='N')
{
printf("\t\t模擬通話開始!\n");
printf("\t\t請選擇通話型別(1.呼叫(call) OR 2.被呼叫(called)):");
scanf("\t\t%d",&m);
do
{
i=0;
if(m!=1&&m!=2)
{
i=1;
printf("\t\t您輸入序號不在標準中,請重新輸入:");
scanf("\t\t%d",&m);//選擇修改內容
}
}while(i);
n=call();
if(1==m)
save(n,cal);
else if(2==m)
save(n,caled);
printf("\t\t是否繼續模擬?(Y/N)");
scanf("\t\t%c",&flag);
}
return 0;
}
int main()
{
/*head->next=NULL;
system("cls");
printf("\n\t\t**********通訊錄管理系統**********\n");
printf("\t\t┌-------------------------------┐\n");
printf("\t\t│ 1.新增聯絡人 │\n");
printf("\t\t│ 2.查詢聯絡人 │\n");
printf("\t\t│ 3.刪除聯絡人 │\n");
printf("\t\t│ 4.修改聯絡人資訊 │\n");
printf("\t\t│ 5.輸出聯絡人列表 │\n");
printf("\t\t│ 6.排序 │\n");
printf("\t\t│ 7.寫入檔案 │\n");
printf("\t\t│ 8.讀取檔案 │\n");
printf("\t\t│ 9.通話記錄 │\n");
printf("\t\t│ 0.退出 │\n");
printf("\t\t└-------------------------------┘\n");
printf("\t\t請您選擇(0-9):");
printf("\n\t\t******************************通訊錄列表******************************\n");
printf("\t\t姓名\t\t手機號碼\tQQ號碼\t\t電子郵箱\n");*/
head->next=NULL;
for(;;)
{
switch(menu_select())
{
case 1:
printf("\n\t\t新增記錄到通訊錄\n"); //新增記 錄
Addpeo();
system("pause");
break;
case 2:
printf("\n\t\t在通訊錄中查詢聯絡人\n");
watch_over();
system("pause");
break;
case 3:
printf("\n\t\t從通訊錄中刪除聯絡人\n");
Delete();
system("pause");
break;
case 4:
printf("\n\t\t修改通訊錄中的資訊\n");
change();
system("pause");
break;
case 5:
printf("\n\t\t輸出通訊錄列表\n");
display();
system("pause");
break;
case 6:
printf("\n\t\t排序\n");
arrange();
system("pause");
break;
case 7:
printf("\n\t\t寫入檔案\n");
write();
system("pause");
break;
case 8:
printf("\n\t\t讀取檔案\n");
read();
system("pause");
break;
case 9:
printf("\n\t\t模擬通話\n");
chat_record();
system("pause");
break;
case 0:
printf("\n\t\t謝謝使用,再見!\n"); //結束程式
printf("\n\t\t");
system("pause");
exit(0);
}
}
return 0;
}
四、除錯和執行
本次課設除錯基本上沒有出現什麼大問題,都是一些比較細微的問題,其中某個問題是值得注意的,描述如下:
while(p!=NULL&&strcmp(p->chat.name,nm)!=0)p=p->next;//這是正確的形式
而之前,我是這樣寫的 while(strcmp(p->chat.name,nm)!=0&&p!=NULL)p=p->next;
這就有個問題,當我們的連結串列到達鏈尾時,由於其為空,故當我們先判斷strcmp(p->chat.name,nm)!=0時會出現錯誤,因為此時的p不指向任何一個地址。
五、總結(心得體會)
此次的通訊錄管理系統總體的難度並不是很難,難的是不斷地填充必要或是人性化的功能,以及各個部分分工合理不發生衝突。當然,最重要的還是整個過程沉得下心的心性。
另外,當我們真正的進入社會工作時,絕沒有像我們這次課設一樣簡單,我們如今的工作量或許只是將來我們某個專案中毫不起眼的一項,或許根本就不及,所以,社會工作經驗是很重要的。