題目:手機通信錄管理系統
一、題目要求
二、需求分析
三、設計步驟/編寫代碼
四、上機/運行結果
五、總結
一、題目要求
模擬手機通信錄管理系統,實現對手機中的通信錄進行管理操作。功能要求:
(1)查看功能:A:辦公,B:個人,C:商務
(2)增加聯系人:錄入新數據(姓名,電話,分類,郵箱:weiyang,153********,個人,klyweiwei@163.com)
(3)修改功能:選中某人的姓名,可對其數據進行修改操作
(4)刪除功能:選中某人姓名,可對此人的相應數據進行刪除,並自動調整后續條目的編號。
二、需求分析
根據題目要求,由於通信錄信息是存放在文件中,所以應提供文件的輸入、輸出等操作;在程序中需要瀏覽個人的信息,應提供顯示、查找、增加、刪除等操作;另外還應提供鍵盤式選擇菜單實現功能選擇。
三、設計步驟/編寫代碼
根據上面的需求分析,可以將這個系統的設計分為如下六大模塊:查找、增加、修改、刪除、顯示、退出。如下圖示:

1、詳細步驟
主函數一般設計得比較簡潔,只提供輸入,處理和輸出部分的函數調用。其中各功能模塊用菜單方式選擇。主函數流程圖如下:

/***************菜單*****************/
void menu() /*主界面*/ { int n,w1;/*變量n保存選擇菜單數字,w判斷輸入的數字是否在功能菜單對應數字范圍內*/ do { puts("\t\t**************MENU****************\n\n"); puts("\t\t\t\t 1. 查詢成員資料"); puts("\t\t\t\t 2. 增加一位成員資料"); puts("\t\t\t\t 3. 修改一位成員資料"); puts("\t\t\t\t 4. 刪除一位成員資料"); puts("\t\t\t\t 5. 成員總名單查看"); puts("\t\t\t\t 6. 退出系統"); puts("\n\n\t\t*********************************\n"); printf("請選擇您要執行的功能(1-6):[ ]\b\b"); scanf("%d",&n); if(n<1||n>5) { w1=1;getchar(); } else w1=0; }while(w1==1); switch(n) {case 1:search();break; /*查看模塊*/
case 2:add();break; /*增加模塊*/
case 3:modify();break; /*修改模塊*/
case 4:del();break; /*刪除模塊*/
case 5:browse();break; /*顯示模塊*/
case 6:exit(0); /*退出*/ } } /***************主函數****************/ main () main () { menu (); }
2、功能模塊設計
(1)查看模塊
原始數據只有一類,為個人通訊錄信息,Name: person.txt。單獨看各數據信息,姓名,分類,電話,郵箱都是字符型,可以采用字符型數組。
要考慮的問題是:一個人的記錄從文件中讀出來后以什么形式存放?似乎也很容易想到:可以采用結構體的形式。這樣把個人通信信息的姓名、電話號碼等作為結構體成員不就可以把一個人的信息作為一個整體來處理
了嗎?如果要存放若干個人的信息就用結構體數組。

struct person { char name[10]; char phone[11]; char classify[10]; char email[20]; } per[N]; char A[]={"office"}; char B[]={"personal"}; char C[]={"business"};
per[N]中N為所有記錄人的個數,程序中采用宏定義的方式,可以隨時在源程序宏定義中改,本程序宏定義#define N 15。同時還定義三種分類:辦公類、個人類、商務類。
/***************查看功能**************/ search() { void menu(); int n,j,k=-1; char p[10]; n=load(); printf("\n\nClassify A:office\nClassify B:single\nClassify C:business\n\n Enter classify that you want to search! Classify:"); /*************輸入要找的人的分類*********/ scanf("%s",p); for(j=0;j<n;j++) if(strcmp(p,per[j].classify)==0) { k=j; printf("\n(%d).%s %s\n",j,per[j].name,per[j].phone); } if(k==-1) /**********如果要查找的分類不存在,則顯示不存在**********/ { printf("\n\nNO EXIST!"); } menu(); }
(2)增加模塊
該模塊的功能是:能錄入新數據每個結點包括:姓名,電話號碼,分類(辦公類、個人類、商務類),電子郵件。當錄入重復的姓名和電話號碼時,則提示數據錄入重復並取消錄入;當通訊錄中超過15條信息時,存儲空間已滿,不能再錄入新數據;錄入的新數據能按遞增的順序自動進行條目編號。

/**************增加功能*********/
void add() { void menu(); int n,j; FILE *fp; char name[10],classify[10],email[20]; char phone[11]; n=load(); printf("\n\nThe name and phone of the person you want to add are:\n\n"); /******輸入要增加人的姓名和電話號碼******/ scanf("%s%s",name,phone); if((fp=fopen("person.txt","r+"))==NULL) { printf("\n\nCan not open!\n\n"); } for(j=0;j<n;j++) { if(strcmp(name,per[j].name)==0&&strcmp(phone,per[j].phone)==0)/*如果輸入的姓名和電話已存在,則提示已存在*/ { printf("\n\nThe message is exist!\n");break; } } if(j==15) { //if(j>=15)
printf("\n\nThe room is full!\n\n");/*如果記錄多余15條,則提示空間已滿*/ } else { printf("\nOK!Put the classify and email:\n"); /****如果輸入的是新信息,則繼續輸入這個人的分類和電子郵件*****/ scanf("%s%s",classify,e_mile); fseek(fp,0,2); fprintf(fp,"\n%s %s %s %s",name,phone,classify,email); } fclose(fp); menu();
(3)修改模塊
該模塊的功能是:根據選中某人的姓名查找此人的通訊記錄,並提示用戶修改記錄的哪部分信息(姓名,電話,分類,電子郵件)。

/****************修改功能************/
void modify() { int i,n,j,c; char name[10]; FILE *fp; n=load(); printf("\n\nModify by name:\n"); /*****輸入要修改人的姓名******/ scanf("%s",name); if((fp=fopen("person.txt","r+"))==NULL) { printf("\n\nCan not open!\n\n"); } for(j=0;j<n;j++) if(strcmp(name,per[j].name)==0) { do { puts("\nModify by=>\n\n 1).name 2).phone: 3).classify: 4).email:"); printf("Whitch you needed?:[ ]\b\b"); /*******輸入要修改的選項********/ scanf("%d",&c); if(c>4||c<1) { puts("\nChioce error!Please again!"); getchar(); } } while(c>8||c<1);break; } do { switch(c) { case 1:printf("name");scanf("%s",per[j].name);break; case 2:printf("phone");scanf("%s",per[j].phone);break; case 3:printf("classify");scanf("%s",per[j].classify);break; case 4:printf("e_mile");scanf("%s",per[j].email);break; } } while(c<1||c>4); if(j==n) printf("\n\nThe name you want is not exist!\n"); for(i=0;i<n;i++) fprintf(fp,"%s %s %s%s\n",per[i].name,per[i].phone,per[i].classify,per[i].email); fclose(fp); menu (); }
(4)刪除模塊
該模塊的功能是按用戶輸入個人的姓名刪除此人的全部信息。做法是保存未被刪除的所有信息,即實現功能,並且自動調整后續條目的編號。這樣比起刪除一般做法較為簡單。

/******************刪除功能****************/
void del() { int i,j,n; FILE *fp; char name[10]; n=load(); printf("\n\nDel by name:"); /******輸入要刪除人的姓名********/ scanf("%s",name); if((fp=fopen("person.txt","w"))==NULL) { printf("\n\nCan not open!\n\n"); } for(j=0;j<n;j++) if(strcmp(name,per[j].name)==0) break; for(i=0;i<n;i++) if(i!=j) /********刪除選項,並自動調整其他所有選項*************/ fprintf(fp,"%s%s%s%s\n",per[i].name,per[i].phone,per[i].classify,per[i].email); fclose(fp); menu(); }
(5)顯示模塊
/****************顯示功能***************/
void browse() { void menu(); int n,i; n=load(); for(i=0;i<n;i++) { printf("\n(%d).%s-%s-%s-%s\n",i,per[i].name,per[i].phone,per[i].classify,per[i].email); } menu(); }
(6)公共函數
每個模塊都會用到的公共函數。加載函數 load()。如下程序用於加載所有記錄,並可以返回所有記錄的個數。
int load()/**********加載函數**********/
/***********加載所有記錄,並且可以返回所有記錄的個數********/ { FILE *fp; int i; if((fp=fopen("person.txt","r"))==NULL) { printf("\nCannot open file\n"); return 0; } for(i=0;!feof(fp);i++) { fscanf(fp,"%s%s%s%s",&per[i].name,&per[i].phone,&per[i].classify,&per[i].emai); email); } fclose(fp); return(i); }
四、上機/運行結果
1、數據
Lic 11111111 A Lic@126.com
WangH 22222222 A WangH@126.com
XvX 33333333 A XvX@126.com
ZhaoL 44444444 B ZhaoL@126.com
ChenG 55555555 B ChenG@126.com
ZhangP 66666666 C ZhangP@126.com
YangW 77777777 C YangW@126.com
LiX 88888888 C LiX@126.com
ZhangR 99999999 C ZhangR@126.com
2、編譯、運行
3、結果
(1)主菜單函數

(2)查看模塊

輸入C

(3)增加模塊
。。。
。。。
有興趣的同學可以測試一下。
五、總結
學以致用,經過上次的電話面試,我下決心一定要把通信錄研究透徹。
注意事項:本代碼用Dev C++編譯。
附錄:源代碼
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define N 15
struct person
{
char name[10];
char phone[11];
char classify[10];
char email[20];
}per[N];
char A[]={"office"};
char B[]={"personal"};
char C[]={"business"};
int load()//**********加載函數**********/
/***********加載所有記錄,並且可以返回所有記錄的個數********/
{
FILE *fp;
int i;
if((fp=fopen("person.txt","r"))==NULL)
{
printf("\nCannot open file\n");
return 0;
}
for(i=0;!feof(fp);i++)
fscanf(fp,"%s%s%s%s",&per[i].name,&per[i].phone,&per[i].classify,&per[i].email);
fclose(fp);
return(i);
}
/***************查看功能**************/
search()
{
void menu();
int n,j,k=-1;
char p[10];
n=load();
printf("\n\nClassify A:office\nClassify B:single\nClassify C:business\n\n Enter classify that you want to search! Classify:"); /*************輸入要找的人的分類*********/
scanf("%s",p);
for(j=0;j<n;j++)
if(strcmp(p,per[j].classify)==0)
{
k=j;
printf("\n(%d).%s %s\n",j,per[j].name,per[j].phone);
}
if(k==-1)
/**********如果要查找的分類不存在,則顯示不存在**********/ {
printf("\n\nNO EXIST!");
}
menu();
}
/**************增加功能*********/
void add()
{
void menu(); int n,j;
FILE *fp;
char name[10],classify[10],email[20];
char phone[11];
n=load();
printf("\n\nThe name and phone of the person you want to add are:\n\n");
/******輸入要增加人的姓名和電話號碼******/
scanf("%s%s",name,phone);
if(!(fp=fopen("person.txt","r+"))==NULL)
{
printf("\n\nCan not open!\n\n");
}
for(j=0;j<n;j++)
{ if(strcmp(name,per[j].name)==0&&strcmp(phone,per[j].phone)==0)/*如果輸入的姓名和電話已存在,則提示已存在*/
{
printf("\n\nThe message is exist!\n");break;
}
}
if(j==15)
{
//if(j>=15)
printf("\n\nThe room is full!\n\n");/*如果記錄多余15條,則提示空間已滿*/
}
else
{
printf("\nOK!Put the classify and email:\n");
/****如果輸入的是新信息,則繼續輸入這個人的分類和電子郵件*****/ scanf("%s%s",classify,email);
fseek(fp,0,2);
fprintf(fp,"\n%s %s %s %s",name,phone,classify,email); }
fclose(fp);
menu();
}
/****************修改功能************/
void modify()
{
void menu() ;
int i,n,j,c; char name[10];
FILE *fp;
n=load();
printf("\n\nModify by name:\n");
/*****輸入要修改人的姓名******/
scanf("%s",name);
if((fp=fopen("person.txt","r+"))==NULL)
{
printf("\n\nCan not open!\n\n");
}
for(j=0;j<n;j++)
if(strcmp(name,per[j].name)==0)
{
do
{ puts("\nModifyby=>\n\n1).name2).phone:3).classify:4).email:"); printf("Whitch you needed?:[ ]\b\b");
/*******輸入要修改的選項********/
scanf("%d",&c);
if(c>4||c<1)
{
puts("\nChioce error!Please again!");
getchar();
}
}
while(c>8||c<1);break;
}
do
{ switch(c)
{
case 1:printf("name");scanf("%s",per[j].name);break;
case 2:printf("phone");scanf("%s",per[j].phone);break;
case 3:printf("classify");scanf("%s",per[j].classify);break;
case 4:printf("email");scanf("%s",per[j].email);break;
}
}
while(c<1||c>4);
if(j==n) printf("\n\nThe name you want is not exist!\n"); for(i=0;i<n;i++)
fprintf(fp,"%s %s %s %s\n",per[i].name,per[i].phone,per[i].classify,per[i].email);
fclose(fp);
menu ();
}
/******************刪除功能****************/
void del() {
void menu();
int i,j,n;
FILE *fp;
char name[10];
n=load();
printf("\n\nDel by name:");
/******輸入要刪除人的姓名********/
scanf("%s",name);
if((fp=fopen("person.txt","w"))==NULL)
{
printf("\n\nCan not open!\n\n");
}
for(j=0;j<n;j++)
if(strcmp(name,per[j].name)==0)
break;
for(i=0;i<n;i++) if(i!=j)
/********刪除選項,並自動調整其他所有選項*************/
fprintf(fp,"%s%s%s%s\n",per[i].name,per[i].phone,per[i].classify,per[i].email);
fclose(fp);
menu();
}
/****************顯示功能***************/
void browse() {
void menu();
int n,i;
n=load();
for(i=0;i<n;i++) {
printf("\n(%d).%s-%s-%s-%s\n",i,per[i].name,per[i].phone,per[i].classify,per[i].email);
}
menu();
}
/***************菜單*****************/
void menu()
{
int n,w1;/*變量n保存選擇菜單數字,w判斷輸入的數字是否在功能菜單對應數字范圍內*/
do
{
puts("\t\t**********通訊錄主界面**********\n\n");
puts("\t\t\t\t 1. 查詢成員資料"); puts("\t\t\t\t 2. 增加一位成員資料");
puts("\t\t\t\t 3. 修改一位成員資料"); puts("\t\t\t\t 4. 刪除一位成員資料");
puts("\t\t\t\t 5. 成員總名單查看");
puts("\t\t\t\t 6. 退出系統"); puts("\n\n\t\t*********************************\n"); printf("Choice your number(1-6):[ ]\b\b"); scanf("%d",&n); if(n<1||n>6)
{w1=1;getchar();}
else w1=0;
}
while(w1==1);
switch(n)
{
case 1:search();break; /*查看模塊*/
case 2:add();break; /*增加模塊*/
case 3:modify();break; /*修改模塊*/
case 4:del();break; /*刪除模塊*/
case 5:browse();break; /*顯示模塊*/
case 6:exit(0); /*退出*/
}
}
/***************主函數****************/
main ()
{
menu ();
}
