文章目錄
- 一、通訊錄的要求
- 二、通訊錄的具體實現
- 0、 準備工作
- 1、通訊錄的初始化
- 2、通訊錄的銷毀
- 3、通訊錄的展示
- 4、通訊錄添加數據
- 5、通訊錄刪除數據
- 6、通訊錄的查找
- 7、通訊錄的修改
- 8、保存通訊錄數據到文件
- 9、讀取文件內容到通訊錄
- 三、 通訊錄的完整實現
一、通訊錄的要求
通訊錄所能實現的功能要求如下:
1)?少能夠存儲100個?的通訊信息
2)能夠保存??信息:名字、性別、年齡、電話、地址等
3)增加聯系?
4)刪除指定聯系?
5)查找指定聯系?
6)修改指定聯系?
7)顯?聯系?信息
二、通訊錄的具體實現
0、 準備工作
注:本文所有的SeqList文件均在上文講解過,如果有不懂的可以點擊藍色字體查看上文。
通訊錄的實現是基于動態順序表實現的,可以理解為在動態順序表上面套了一層殼子叫做通訊錄,里面的核心還是動態順序表。
由此圖可以理解為原來動態順序表的一個元素,現在變成了一個結構體(包含了聯系人的信息)。
由于是在動態順序表的基礎上實現的,所以還需要包含前文所寫的SeqList.h和SeqList.c文件,因此要實現通訊錄需要包含5個文件:
SeqList.h
SeqList.c:
Contact.h:通訊錄函數的聲明,結構體構造,宏定義。
Contact.c:通訊錄函數的實現。
test.c:通訊錄函數的測試
如果要實現通訊錄,那我們首先需要定義一個聯系人的結構體,包含聯系人的各種信息。
即:
這些信息僅做參考,還可以根據需求自己定義一些相關信息。
結構體在通訊錄的頭文件Contact.h中定義:
typedef struct PersonInfo
{char name[10];//姓名char sex[10];//性別int age;//年齡char tel[20];//電話char addr[100];//地址
}Peo
但是為了便于維護,我們可以將數組的最大值用宏定義來替代,提高代碼的便利性。
即:
#define NAME_MAX 10
#define SEX_MAX 10
#define TEL_MAX 20
#define ADDR_MAX 100typedef struct PersonInfo
{char name[NAME_MAX];//姓名char sex[SEX_MAX];//性別int age;///年齡char tel[TEL_MAX];//電話char addr[ADDR_MAX];//地址
}PeoInfo;
之前在順序表中,一個元素的類型一般是int類型,現在我們用結構體替代原來的元素,元素類型應該變成結構體類型PeoInfo。
因此需要將SeqList.h文件中的:
typedef int SLDataType;
改為:
typedef PeoInfo SLDataType;
而在SeqList.h文件中引用Contact.h文件中的內容,需要在SeqList.h中添加#include"Contact.h"
。
由于我們實質上是對順序表進行操作,所以需要對在Contact.h中為順序表重新起個名字叫做通訊錄:
typedef struct SeqList Contact;
接下來就進入正式部分,首先對需要實現的通訊錄相關的方法在Conatct.h中進行聲明:
//通訊錄的初始化
void ContactInit(Contact* con);//通訊錄的銷毀
void ContactDestroy(Contact* con);//通訊錄的展示
void ContactShow(Contact* con);//通訊錄添加數據
void ContactAdd(Contact* con);//通訊錄刪除數據
void ContactDel(Contact* con);//通訊錄的查找
void ContactFind(Contact* con);//通訊錄的修改
void ContactModify(Contact* con);//保存通訊錄數據到文件
void SaveContact(Contact* con);//讀取文件內容到通訊錄
void LoadContact(Contact* con);
接下來再在Contact.c文件中來實現方法,首要需要引用頭文件:#include"Contact.h"
,同時實現的部分方法是直接使用的順序表的方法,因此還需要引用順序表:#include"SeqList.h"
。
現在完事具備,可以來實現方法了。
1、通訊錄的初始化
通訊錄的初始化:直接調用順序表的初始化。
void ContactInit(Contact* con)
{//調用順序表的初始化SLInit(con);
}
在test.c中進行測試:
int main()
{Contact con;ContactInit(&con);return 0;
}

通過測試發現通訊錄初始化成功!
2、通訊錄的銷毀
通訊錄的銷毀:同樣直接調用順序表的銷毀即可。
void ContactDestroy(Contact* con)
{//調用順序表的銷毀SLDestroy(con);
}
再進行測試:
int main()
{Contact con;ContactInit(&con);ContactDestroy(&con);return 0;
}

3、通訊錄的展示
通訊錄的展示:先打印表頭,再依次打印通訊錄中每一個結構體里的五個通訊錄信息。
void ContactShow(Contact* con)
{//打印表頭printf("%-10s %-4s %-4s %-11s %-20s\n", "姓名", "性別", "年齡", "電話", "地址");//for循環依次打印通訊錄中每一個(元素)結構體里的5個通訊錄信息for (int i = 0; i < con->size; i++){printf("%-10s %-4s %-4d %-11s %-20s\n",con->arr[i].name,con->arr[i].sex,con->arr[i].age,con->arr[i].tel,con->arr[i].addr);}
}
注:-號表示左對齊,10表示輸出的數據占10個字符。
再進行測試:
int main()
{Contact con;ContactInit(&con);ContactShow(&con);return 0;
}

通過測試發現通訊錄展示成功!
4、通訊錄添加數據
通訊錄添加數據:輸入一個元素的通訊錄信息,再尾插到通訊錄(順序表)中。
void ContactAdd(Contact* con)
{//輸入一個元素(結構體)的通訊錄信息PeoInfo info;printf("請輸入要添加的聯系人姓名:");scanf("%s", info.name);//數組不用取地址&printf("請輸入要添加的聯系人性別:");scanf("%s",info.sex);printf("請輸入要添加的聯系人年齡:");scanf("%d", &info.age);printf("請輸入要添加的聯系人電話:");scanf("%s", info.tel);printf("請輸入要添加的聯系人地址:");scanf("%s", info.addr);//將其尾插到通訊錄(順序表)中SLPushBack(con, info);printf("聯系人數據添加成功!\n");
}
再進行測試:
int main()
{Contact con;ContactInit(&con);ContactAdd(&con);ContactShow(&con);return 0;
}

通過測試發現通訊錄添加數據成功!
5、通訊錄刪除數據
在進行刪除、查找等操作的時候,我們需要通過姓名這個唯一性元素來得到其整個信息,然后再進行操作。
根據姓名查找:遍歷通訊錄,找到返回下標,否則返回-1
int FindByName(Contact* con, char Name[])
{//遍歷通訊錄,查看通訊錄每一個元素中的姓名是否與傳入的姓名相同for (int i = 0; i < con->size; i++){if (0 == strcmp(con->arr[i].name, Name)){//返回下標return i;}}//找不到return -1;
}
接下來再進行通訊錄的刪除:輸入姓名,找到下標,調用順序表指定位置刪除,刪除下標對應的數據。
void ContactDel(Contact* con)
{//輸入要刪除的姓名char Name[NAME_MAX];printf("請輸入你要刪除的聯系人姓名:");scanf("%s", Name);//找到下標int find = FindByName(con, Name);if (find < 0){printf("你要刪除的聯系人數據不存在!\n");}//調用順序表指定位置的刪除 刪除下標對應的數據SLErase(con, find);printf("聯系人數據刪除成功!\n");
}
再進行測試:
int main()
{Contact con;ContactInit(&con);ContactAdd(&con);ContactShow(&con);ContactDel(&con);ContactShow(&con);return 0;
}

通過測試發現通訊錄數據刪除成功!
6、通訊錄的查找
通訊錄的查找:輸入姓名,找到下標,打印下標對應的數據。
void ContactFind(Contact* con)
{//輸入要查找的姓名char Name[NAME_MAX];printf("請輸入你要查找的聯系人姓名:");scanf("%s", Name);//找到下標int find = FindByName(con, Name);if (find < 0){printf("你要查找的聯系人數據不存在!\n");}//打印下標對應的數據printf("%-10s %-4s %-4s %-11s %-20s\n", "姓名", "性別", "年齡", "電話", "地址");printf("%-10s %-4s %-4d %-11s %-20s\n",con->arr[find].name,con->arr[find].sex,con->arr[find].age,con->arr[find].tel,con->arr[find].addr );
}
再進行測試:
int main()
{Contact con;ContactInit(&con);ContactAdd(&con);ContactShow(&con);ContactFind(&con);return 0;
}

通過測試發現通訊錄查找成功!
7、通訊錄的修改
通訊錄的修改:輸入姓名,找到下標,修改下標對應的數據。
void ContactModify(Contact* con)
{//輸入姓名char Name[NAME_MAX];printf("請輸入你要修改的聯系人姓名:");scanf("%s", Name);//找到下標int find = FindByName(con, Name);if (find < 0){printf("你要修改的聯系人數據不存在!\n");}//修改下標對應的數據printf("請輸入新的聯系人姓名:");scanf("%s", con->arr[find].name);printf("請輸入新的聯系人性別:");scanf("%s", con->arr[find].sex);printf("請輸入新的聯系人年齡:");scanf("%d", &con->arr[find].age);printf("請輸入新的聯系人電話:");scanf("%s", con->arr[find].tel);printf("請輸入新的聯系人地址:");scanf("%s", con->arr[find].addr);printf("聯系人數據修改成功!\n");
}
再進行測試:
int main()
{Contact con;ContactInit(&con);ContactAdd(&con);ContactShow(&con);ContactModify(&con);ContactShow(&con);return 0;
}

經過測試通訊錄的修改成功!
8、保存通訊錄數據到文件
保存數據到文件:打開文件,聯系人數據寫入文件,關閉文件。
void SaveContact(Contact* con)
{//打開文件FILE* pf = fopen("Contact.txt", "ab");//如果打開失敗{if (pf == NULL){perror("fopen fail");}}//將聯系人數據寫入文件for (int i = 0; i < con->size; i++){fwrite(con->arr + i, sizeof(PeoInfo), 1, pf);}printf("通訊錄數據保存成功!\n");//關閉文件fclose(pf);
}
再進行測試:
int main()
{Contact con;ContactInit(&con);ContactAdd(&con);ContactShow(&con);SaveContact(&con);return 0;
}

同時我們可以點擊添加源文件,添加現有項,將Contact.txt文件添加進來,再將txt文件的打開方式設置為二進制編輯器。‘’
就可以在Contact.txt文件中看到;
說明數據已經以二進制的形式保存在文件中了。
9、讀取文件內容到通訊錄
讀取文件內容到通訊錄:打開文件,讀取文件,尾插到通訊錄中,關閉文件。
void LoadContact(Contact* con)
{//打開文件FILE* pf=fopen("Contact.txt","rb");//如果打開失敗if (pf == NULL){perror("fopen fail");}//讀取文件數據PeoInfo info;while (fread(&info, sizeof(PeoInfo), 1, pf)){//文件數據尾插到通訊錄中SLPushBack(con, info);}//關閉文件fclose(pf);
}
再進行測試:
int main()
{Contact con;ContactInit(&con);ContactShow(&con);LoadContact(&con);ContactShow(&con);return 0;
}

可以觀察到,一開始原本沒有數據,但是在我們讀取文件到通訊錄之后,就有了數據,說明讀取文件內容到通訊錄成功了!
三、 通訊錄的完整實現
在我們實現了通訊錄的所有方法之后,我們可以將其集合起來做成完整的通訊錄。
再在test.c中來實現這個完整的程序:
#define _CRT_SECURE_NO_WARNINGS
#include"SeqList.h"//打印通訊錄界面
void menu()
{printf("************** 通訊錄 **************\n");printf("******* 1.增加聯系人 2.刪除聯系人 ******\n");printf("******* 3.修改聯系人 4.查找聯系人 ******\n");printf("******* 5.展示聯系人 6.保存聯系人 ******\n");printf("******* 7.導入聯系人 0.退出 ******\n");printf("********************************************\n");
}int main()
{//通訊錄初始化int input = -1;Contact con;ContactInit(&con);//用do while先執行一次循環,輸入0循環結束do{menu();//輸入序號printf("請選擇你要執行的操作:");scanf("%d", &input);//根據輸入的序號執行對應的操作 switch (input){case 1:ContactAdd(&con);break;case 2:ContactDel(&con);break;case 3:ContactModify(&con);break;case 4:ContactFind(&con);break;case 5:ContactShow(&con);break;case 6:SaveContact(&con);break;case 7:LoadContact(&con);break;case 0:printf("退出通訊錄...\n");break;default:printf("輸入錯誤,請重新選擇你的操作:\n");break;} } while (input != 0);//通訊錄銷毀ContactDestroy(&con);return 0;
}
效果如下: