
一.靜態(tài)版本
1.所需要的功能
對于通訊錄來說,我們需要它實現(xiàn)以下幾個功能。
1.人的信息:姓名+年齡+性別+電話+地址。
2.可以存放100個人的信息。
功能:
1>增加聯(lián)系人。
2>刪除聯(lián)系人。
3>查找指定聯(lián)系人信息。
4>修改指定聯(lián)系人信息。
5>顯示所有聯(lián)系人信息。
6>按名字排序。
接下來分為三個模塊,test.c->用來測試通訊錄;contact.c->通訊錄主體部分;contact.h->用于函數(shù)的聲明。
2.大致菜單
#include"contact.h"
void menu()
{
printf("********************************\n");
printf("****** 1.增加 2.刪除 ******\n");
printf("****** 3.查找 4.修改 ******\n");
printf("****** 5.展示 6.排序 ******\n");
printf("*******0.退出 ******\n");
printf("********************************\n");
}
int main()
{
int input = 0;
do
{
menu();
scanf("%d", &input);
switch (input)
{
case 1:
break;
case 2:
break;
case 3:
break;
case 4:
break;
case 5:
break;
case 6:
break;
case 0:
printf("退出通訊錄。\n");
break;
default:
printf("輸入無效,請重新輸入。\n");
break;
}
} while (input);
return 0;
}
這一塊很簡單,就不再多說。菜單是屬于測試部分,所以我將它放入test.c文件里。
3.創(chuàng)建通訊錄
對于一個人,肯定有多方面的因數(shù),所以將其封裝在一個結構體內。這里使用到typedef,如果不太熟悉可以看看這篇博客typedef的使用
接下來,再封裝一個結構體里面存放100個人的信息和當前人的個數(shù)。
接著在主函數(shù)里使用該結構體創(chuàng)建通訊錄。然后進行初始化。
初始化函數(shù)在contact.h里聲明。
在contact.c里實現(xiàn),需要使用到memset,如果不太明白可以看看這篇博客memset如何使用
4.增加聯(lián)系人
在contact.h里聲明。
在contact.c里面實現(xiàn)。
5.顯示聯(lián)系人
在contact.h里聲明。
在contact.c里實現(xiàn)。這里使用到\t,向后隔開8個字節(jié),用于分隔。同時例如%-20s是右邊隔開20個字節(jié),也就是進行左對齊。
6.查找聯(lián)系人
我們發(fā)現(xiàn)無論是查找,刪除還是修改都需要先找到這個人。所以我們干脆將尋找封裝成一個函數(shù)來使用。我們通過名字來查找(需要使用strcmp,如果不熟悉可以看看這篇博客strcmp的使用)
完成后正式進行查找。
老規(guī)矩,現(xiàn)在contact.h里進行聲明。ps:前面的find不用聲明是因為find只在contact.c里使用。
在contact.c里實現(xiàn)。
7.刪除聯(lián)系人
這里采用一種最簡單的方法,就是從后往前依次覆蓋。首先找到該名字的位置,然后依次將后面的往前挪。
在contact.h里聲明。
在contact.c里實現(xiàn)。
8.修改聯(lián)系人
老規(guī)矩在contact.h里進行聲明。
在contact.c里實現(xiàn)。修改其實就是重新錄入,找到位置,重新寫一遍就好了。
9.按名字排序
下面排序需要使用到qsort函數(shù)。如果不太熟悉可以看看這篇博客qsort函數(shù)
老規(guī)矩在contact.h里聲明。
在contact.c里實現(xiàn)。
好了,以上就是通訊錄靜態(tài)版本的實現(xiàn)功能啦,下面是源代碼。
10.源代碼
test.c
#include"contact.h"
void menu()
{
printf("********************************\n");
printf("****** 1.增加 2.刪除 ******\n");
printf("****** 3.查找 4.修改 ******\n");
printf("****** 5.展示 6.排序 ******\n");
printf("*******0.退出 ******\n");
printf("********************************\n");
}
int main()
{
int input = 0;
//創(chuàng)建通訊錄
Contact con;//該結構體包含100個人的信息和已填充人的個數(shù)
//初始化通訊錄
InitContact(&con);//結構體傳參
do
{
menu();
printf("請選擇:");
scanf("%d", &input);
switch (input)
{
case 1:
AddContact(&con);
break;
case 2:
Dlete(&con);
break;
case 3:
Search(&con);
break;
case 4:
Modify(&con);
break;
case 5:
ShowContact(&con);
break;
case 6:
Order(&con);
break;
case 0:
printf("退出通訊錄。\n");
break;
default:
printf("輸入無效,請重新輸入。\n");
break;
}
} while (input);
return 0;
}
contact.h
#include<stdio.h>
#include<string.h>
#include<assert.h>
//人的信息
typedef struct PeoInfo
{
char name[20];
int age;
char sex[5];
char addr[30];
char tele[12];
}PeoInfo;
typedef struct Contact
{
PeoInfo data[100];//存放人的信息
int sz;//當前已經(jīng)放的信息個數(shù)
}Contact;//同理,這里也進行了重命名
//聲明初始化函數(shù)
void InitContact(Contact* pc);
//聲明增加聯(lián)系人函數(shù)
void AddContact(Contact*pc);
//聲明顯示聯(lián)系人函數(shù)
void ShowContact(const Contact*pc);
//聲明查找函數(shù)
void Search(const Contact*pc);//查找依然不會改變,所以加上const
//聲明刪除函數(shù)
void Dlete(Contact*pc);
//聲明修改函數(shù)
void Modify(Contact*pc);
//聲明排序函數(shù)
void Order(Contact*pc);
contact.c
#include"contact.h"
//初始化函數(shù)的實現(xiàn)
void InitContact(Contact* pc)
{
pc->sz = 0;
memset(pc->data, 0, sizeof(pc->data));
}
//增加聯(lián)系人
void AddContact(Contact* pc)
{
assert(pc);//一個好的習慣判斷是否為空指針(當然不加也沒影響)
if (pc->sz == 100)
{
printf("通訊錄已滿,無法添加。\n");
return;
}
//開始添加信息
printf("請輸入名字:");
scanf("%s", pc->data[pc->sz].name);
printf("請輸入年齡:");
scanf("%d", &(pc->data[pc->sz].age));
printf("請輸入性別:");
scanf("%s", pc->data[pc->sz].sex);
printf("請輸入地址:");
scanf("%s", pc->data[pc->sz].addr);
printf("請輸入電話:");
scanf("%s", pc->data[pc->sz].tele);
pc->sz++;//別忘了添加完一個人后向后走一步
}
//顯示聯(lián)系人
void ShowContact(const Contact* pc)//因為顯示不會改變元素,所以最好加上const
{
assert(pc);
printf("%-20s\t%-4s\t%-5s\t%-20s\t%-12s\n", "名字", "年齡", "性別", "地址", "電話");//提示
for (int i = 0; i < pc->sz; i++)
{
printf("%-20s\t%-4d\t%-5s\t%-20s\t%-12s\n", pc->data[i].name,
pc->data[i].age,
pc->data[i].sex,
pc->data[i].addr,
pc->data[i].tele);
}
}
//找到特定聯(lián)系人的位置
int FindByName(const Contact* pc, char name[])//兩個參數(shù),一個是通訊錄里存的名字,一個是你要查找的名字
{
for (int i = 0; i < pc->sz; i++)
{
if (strcmp(pc->data[i].name, name) == 0)
{
return i;//找到返回下標
}
}
return -1;//沒找到,返回-1
}
//查找
void Search(const Contact* pc)
{
assert(pc);
char name[20] = { 0 };
printf("請輸入要查找的名字:");
scanf("%s", name);
int pos = FindByName(pc, name);
if (pos == -1)
{
printf("查無此人。\n");
return;
}
//找到了,打印信息
printf("%-20s\t%-4d\t%-5s\t%-20s\t%-12s\n", pc->data[pos].name,
pc->data[pos].age,
pc->data[pos].sex,
pc->data[pos].addr,
pc->data[pos].tele);
}
//刪除
void Dlete(Contact* pc)
{
assert(pc);
char name[20] = { 0 };
printf("請輸入要刪除的名字:");
scanf("%s", name);
int dle = FindByName(pc, name);//找到位置
if (dle == -1)
{
printf("查無此人。\n");
return;
}
for (int i = dle; i < pc->sz-1; i++)//從后往前覆蓋,同時-1避免越界
{
pc->data[i] = pc->data[i + 1];
}
pc->sz--;//刪除完成后別忘了個數(shù)-1
printf("刪除成功\n");
}
//修改
void Modify(Contact* pc)
{
assert(pc);
char name[20] = { 0 };
printf("請輸入要修改的名字:");
scanf("%s", name);
int ret = FindByName(pc, name);
if (-1 == ret)
{
printf("查無此人\n");
return;
}
printf("請輸入名字:");
scanf("%s", pc->data[ret].name);
printf("請輸入年齡:");
scanf("%d", &(pc->data[ret].age));
printf("請輸入性別:");
scanf("%s", pc->data[ret].sex);
printf("請輸入地址:");
scanf("%s", pc->data[ret].addr);
printf("請輸入電話:");
scanf("%s", pc->data[ret].tele);
printf("修改成功\n");
}
//排序
int cmp(const void* e1, const void* e2)
{
return strcmp(((PeoInfo*)e1)->name, ((PeoInfo*)e2)->name);
}
void Order(Contact* pc)
{
assert(pc);
qsort(pc->data, pc->sz, sizeof(pc->data[0]), cmp);
printf("排序成功\n");
}
二.動態(tài)版本
動態(tài)版本主要在靜態(tài)版本的基礎上加入擴容功能,如果通訊錄已存滿,那么會自動擴大通訊錄,下面設置初始容量為三個人,如果不滿足每次擴容兩個人。需要的前置知識是動態(tài)內存,如果不太了解,可以看看這篇博客動態(tài)內存
1.修改data數(shù)組
上面的靜態(tài)版本是直接開辟了一個100人的數(shù)組,很明顯已經(jīng)固定。所以應當將這100個人改為動態(tài)的。
靜態(tài)版本
動態(tài)版本
2.修改初始化
在靜態(tài)版本的初始化里直接使用的memset指定具體的字節(jié)數(shù)來初始化。在動態(tài)版本里不知道具體的大小,很明顯不能這么暴力。下面使用calloc對data進行開辟空間的同時完成初始化。
靜態(tài)版本
動態(tài)版本
3.修改增加函數(shù)
在靜態(tài)版本中,如果一直增加聯(lián)系人到通訊錄滿后直接給提升:通訊錄已滿,不能再加入。在動態(tài)版本里需要修改,當放滿通訊錄后自動擴容。
靜態(tài)版本
動態(tài)版本
4.完善通訊錄
上面的修改大致功能沒有問題了,但還有個缺陷是在開辟空間時我們在堆區(qū)上開辟的,所以在程序結束時應當主動free,避免內存泄漏。
在test.c里
在contact.h里
在contact.c里
演示
5.源代碼
test.c
#include"contact.h"
void menu()
{
printf("********************************\n");
printf("****** 1.增加 2.刪除 ******\n");
printf("****** 3.查找 4.修改 ******\n");
printf("****** 5.展示 6.排序 ******\n");
printf("*******0.退出 ******\n");
printf("********************************\n");
}
int main()
{
int input = 0;
//創(chuàng)建通訊錄
Contact con;//該結構體包含100個人的信息和已填充人的個數(shù)
//初始化通訊錄
InitContact(&con);//結構體傳參
do
{
menu();
printf("請選擇:");
scanf("%d", &input);
switch (input)
{
case 1:
AddContact(&con);
break;
case 2:
Dlete(&con);
break;
case 3:
Search(&con);
break;
case 4:
Modify(&con);
break;
case 5:
ShowContact(&con);
break;
case 6:
Order(&con);
break;
case 0:
Destroy(&con);
printf("退出通訊錄。\n");
break;
default:
printf("輸入無效,請重新輸入。\n");
break;
}
} while (input);
return 0;
}
contact.h
#include<stdio.h>
#include<string.h>
#include<assert.h>
#include<stdlib.h>
#define DEFAULT_SZ 3 //初始大小
#define INC_SZ 2 //每次擴容
//人的信息
typedef struct PeoInfo
{
char name[20];
int age;
char sex[5];
char addr[30];
char tele[12];
}PeoInfo;
//動態(tài)版本
typedef struct Contact
{
PeoInfo *data;//指向存放人信息的空間
int sz;//當前已經(jīng)放的信息個數(shù)
int capacity;//當前通訊錄的最大容量
}Contact;
//聲明初始化函數(shù)
void InitContact(Contact* pc);
//聲明銷毀函數(shù)
void Destroy(Contact* pc);
//聲明增加聯(lián)系人函數(shù)
void AddContact(Contact*pc);
//聲明顯示聯(lián)系人函數(shù)
void ShowContact(const Contact*pc);
//聲明查找函數(shù)
void Search(const Contact*pc);//查找依然不會改變,所以加上const
//聲明刪除函數(shù)
void Dlete(Contact*pc);
//聲明修改函數(shù)
void Modify(Contact*pc);
//聲明排序函數(shù)
void Order(Contact*pc);
contact.c
#include"contact.h"
//初始化函數(shù)的實現(xiàn),動態(tài)版本
void InitContact(Contact* pc)
{
pc->sz = 0;
PeoInfo* ptr = (PeoInfo*)calloc(DEFAULT_SZ,sizeof(PeoInfo));//開辟初始空間
if (ptr == NULL)
{
printf("%s", strerror(errno));
return;
}//判斷是否空間開辟成功
pc->data = ptr;
pc->capacity = DEFAULT_SZ;//初始容量為3
}
//銷毀
void Destroy(Contact* pc)
{
free(pc->data);//由于整個data都是在堆區(qū)上開辟的,所以直接free
pc->data = NULL;
pc->capacity = 0;
pc->sz = 0;
pc = NULL;
}
void check_capacity(Contact* pc)
{
if (pc->sz == pc->capacity)//如果容量已滿
{
//增加容量
PeoInfo* ptr =(PeoInfo*)realloc(pc->data, (pc->capacity + INC_SZ) * sizeof(PeoInfo));//調整空間大小
if (ptr == NULL)
{
printf("%s", strerror(errno));
}
pc->data = ptr;//把新空間的起始位置傳給data
pc->capacity += INC_SZ;//最大容量加INC_SZ
printf("增容成功\n");
}
}
//增加聯(lián)系人
void AddContact(Contact* pc)
{
assert(pc);
check_capacity(pc);//檢查容量,判斷是否需要增容
//開始添加信息
printf("請輸入名字:");
scanf("%s", pc->data[pc->sz].name);
printf("請輸入年齡:");
scanf("%d", &(pc->data[pc->sz].age));
printf("請輸入性別:");
scanf("%s", pc->data[pc->sz].sex);
printf("請輸入地址:");
scanf("%s", pc->data[pc->sz].addr);
printf("請輸入電話:");
scanf("%s", pc->data[pc->sz].tele);
pc->sz++;//別忘了添加完一個人后向后走一步
}
//顯示聯(lián)系人
void ShowContact(const Contact* pc)//因為顯示不會改變元素,所以最好加上const
{
assert(pc);
printf("%-20s\t%-4s\t%-5s\t%-20s\t%-12s\n", "名字", "年齡", "性別", "地址", "電話");//提示
for (int i = 0; i < pc->sz; i++)
{
printf("%-20s\t%-4d\t%-5s\t%-20s\t%-12s\n", pc->data[i].name,
pc->data[i].age,
pc->data[i].sex,
pc->data[i].addr,
pc->data[i].tele);
}
}
//找到特定聯(lián)系人的位置
int FindByName(const Contact* pc, char name[])//兩個參數(shù),一個是通訊錄里存的名字,一個是你要查找的名字
{
for (int i = 0; i < pc->sz; i++)
{
if (strcmp(pc->data[i].name, name) == 0)
{
return i;//找到返回下標
}
}
return -1;//沒找到,返回-1
}
//查找
void Search(const Contact* pc)
{
assert(pc);
char name[20] = { 0 };
printf("請輸入要查找的名字:");
scanf("%s", name);
int pos = FindByName(pc, name);
if (pos == -1)
{
printf("查無此人。\n");
return;
}
//找到了,打印信息
printf("%-20s\t%-4d\t%-5s\t%-20s\t%-12s\n", pc->data[pos].name,
pc->data[pos].age,
pc->data[pos].sex,
pc->data[pos].addr,
pc->data[pos].tele);
}
//刪除
void Dlete(Contact* pc)
{
assert(pc);
char name[20] = { 0 };
printf("請輸入要刪除的名字:");
scanf("%s", name);
int dle = FindByName(pc, name);//找到位置
if (dle == -1)
{
printf("查無此人。\n");
return;
}
for (int i = dle; i < pc->sz-1; i++)//從后往前覆蓋,同時-1避免越界
{
pc->data[i] = pc->data[i + 1];
}
pc->sz--;//刪除完成后別忘了個數(shù)-1
printf("刪除成功\n");
}
//修改
void Modify(Contact* pc)
{
assert(pc);
char name[20] = { 0 };
printf("請輸入要修改的名字:");
scanf("%s", name);
int ret = FindByName(pc, name);
if (-1 == ret)
{
printf("查無此人\n");
return;
}
printf("請輸入名字:");
scanf("%s", pc->data[ret].name);
printf("請輸入年齡:");
scanf("%d", &(pc->data[ret].age));
printf("請輸入性別:");
scanf("%s", pc->data[ret].sex);
printf("請輸入地址:");
scanf("%s", pc->data[ret].addr);
printf("請輸入電話:");
scanf("%s", pc->data[ret].tele);
printf("修改成功\n");
}
//排序
int cmp(const void* e1, const void* e2)
{
return strcmp(((PeoInfo*)e1)->name, ((PeoInfo*)e2)->name);
}
void Order(Contact* pc)
{
assert(pc);
qsort(pc->data, pc->sz, sizeof(pc->data[0]), cmp);
printf("排序成功\n");
}
三.文件版本
我們可以發(fā)現(xiàn)前面兩個版本在運行結束后通訊錄里的信息就自動刪除了,很明顯是不符合我們的預期的。這是因為上面的數(shù)據(jù)都儲存在內存中,而內存在一次程序運行結束后會重置,所以我們需要將其寫在硬盤上(文件里),才能保證信息的存儲。(需要的前置知識是文件操作,如果不太熟悉可以看看這篇博客文件操作)
1.退出前保存
test.c里
contact.h里
contact.c里
注意文件可以建在任意位置,但如果不是在當前路徑下,在fopen時記得將該文件的絕對路徑寫上(也就是幾盤,第幾文件夾…)
2.進入后讀取
原來初始化通訊錄時是直接初始化為0,現(xiàn)在初始化時將文件里的信息加載到通訊錄里。
3.源代碼
test.c
#include"contact.h"
void menu()
{
printf("********************************\n");
printf("****** 1.增加 2.刪除 ******\n");
printf("****** 3.查找 4.修改 ******\n");
printf("****** 5.展示 6.排序 ******\n");
printf("*******0.退出 ******\n");
printf("********************************\n");
}
int main()
{
int input = 0;
//創(chuàng)建通訊錄
Contact con;//該結構體包含100個人的信息和已填充人的個數(shù)
//初始化通訊錄
InitContact(&con);//結構體傳參
do
{
menu();
printf("請選擇:");
scanf("%d", &input);
switch (input)
{
case 1:
AddContact(&con);
break;
case 2:
Dlete(&con);
break;
case 3:
Search(&con);
break;
case 4:
Modify(&con);
break;
case 5:
ShowContact(&con);
break;
case 6:
Order(&con);
break;
case 0:
SaveContact(&con);
Destroy(&con);
printf("退出通訊錄。\n");
break;
default:
printf("輸入無效,請重新輸入。\n");
break;
}
} while (input);
return 0;
}
contact.h
#include<stdio.h>
#include<string.h>
#include<assert.h>
#include<stdlib.h>
#define DEFAULT_SZ 3 //初始大小
#define INC_SZ 2 //每次擴容
//人的信息
typedef struct PeoInfo
{
char name[20];
int age;
char sex[5];
char addr[30];
char tele[12];
}PeoInfo;
//動態(tài)版本
typedef struct Contact
{
PeoInfo *data;//指向存放人信息的空間
int sz;//當前已經(jīng)放的信息個數(shù)
int capacity;//當前通訊錄的最大容量
}Contact;
//聲明初始化函數(shù)
void InitContact(Contact* pc);
//聲明銷毀函數(shù)
void Destroy(Contact* pc);
//聲明增加聯(lián)系人函數(shù)
void AddContact(Contact*pc);
//聲明顯示聯(lián)系人函數(shù)
void ShowContact(const Contact*pc);
//聲明查找函數(shù)
void Search(const Contact*pc);//查找依然不會改變,所以加上const
//聲明刪除函數(shù)
void Dlete(Contact*pc);
//聲明修改函數(shù)
void Modify(Contact*pc);
//聲明排序函數(shù)
void Order(Contact*pc);
//聲明保存函數(shù)
void SaveContact(Contact*pc);
//聲明加載通訊錄函數(shù)
void LoadContact(Contact*pc);
contact.c文章來源:http://www.zghlxwxcb.cn/news/detail-803232.html
#include"contact.h"
//初始化函數(shù)的實現(xiàn)
void InitContact(Contact* pc)
{
pc->sz = 0;
PeoInfo* ptr = (PeoInfo*)calloc(DEFAULT_SZ,sizeof(PeoInfo));//開辟初始空間
if (ptr == NULL)
{
printf("%s", strerror(errno));
return;
}//判斷是否空間開辟成功
pc->data = ptr;
pc->capacity = DEFAULT_SZ;//初始容量為3
//加載數(shù)據(jù)到通訊錄
LoadContact(pc);
}
//銷毀
void Destroy(Contact* pc)
{
free(pc->data);//由于整個data都是在堆區(qū)上開辟的,所以直接free
pc->data = NULL;
pc->capacity = 0;
pc->sz = 0;
pc = NULL;
}
void check_capacity(Contact* pc)
{
if (pc->sz == pc->capacity)//如果容量已滿
{
//增加容量
PeoInfo* ptr =(PeoInfo*)realloc(pc->data, (pc->capacity + INC_SZ) * sizeof(PeoInfo));//調整空間大小
if (ptr == NULL)
{
printf("%s", strerror(errno));
}
pc->data = ptr;//把新空間的起始位置傳給data
pc->capacity += INC_SZ;//最大容量加INC_SZ
printf("增容成功\n");
}
}
//增加聯(lián)系人
void AddContact(Contact* pc)
{
assert(pc);
check_capacity(pc);//檢查容量,判斷是否需要增容
//開始添加信息
printf("請輸入名字:");
scanf("%s", pc->data[pc->sz].name);
printf("請輸入年齡:");
scanf("%d", &(pc->data[pc->sz].age));
printf("請輸入性別:");
scanf("%s", pc->data[pc->sz].sex);
printf("請輸入地址:");
scanf("%s", pc->data[pc->sz].addr);
printf("請輸入電話:");
scanf("%s", pc->data[pc->sz].tele);
pc->sz++;//別忘了添加完一個人后向后走一步
}
//顯示聯(lián)系人
void ShowContact(const Contact* pc)//因為顯示不會改變元素,所以最好加上const
{
assert(pc);
printf("%-20s\t%-4s\t%-5s\t%-20s\t%-12s\n", "名字", "年齡", "性別", "地址", "電話");//提示
for (int i = 0; i < pc->sz; i++)
{
printf("%-20s\t%-4d\t%-5s\t%-20s\t%-12s\n", pc->data[i].name,
pc->data[i].age,
pc->data[i].sex,
pc->data[i].addr,
pc->data[i].tele);
}
}
//找到特定聯(lián)系人的位置
int FindByName(const Contact* pc, char name[])//兩個參數(shù),一個是通訊錄里存的名字,一個是你要查找的名字
{
for (int i = 0; i < pc->sz; i++)
{
if (strcmp(pc->data[i].name, name) == 0)
{
return i;//找到返回下標
}
}
return -1;//沒找到,返回-1
}
//查找
void Search(const Contact* pc)
{
assert(pc);
char name[20] = { 0 };
printf("請輸入要查找的名字:");
scanf("%s", name);
int pos = FindByName(pc, name);
if (pos == -1)
{
printf("查無此人。\n");
return;
}
//找到了,打印信息
printf("%-20s\t%-4d\t%-5s\t%-20s\t%-12s\n", pc->data[pos].name,
pc->data[pos].age,
pc->data[pos].sex,
pc->data[pos].addr,
pc->data[pos].tele);
}
//刪除
void Dlete(Contact* pc)
{
assert(pc);
char name[20] = { 0 };
printf("請輸入要刪除的名字:");
scanf("%s", name);
int dle = FindByName(pc, name);//找到位置
if (dle == -1)
{
printf("查無此人。\n");
return;
}
for (int i = dle; i < pc->sz-1; i++)//從后往前覆蓋,同時-1避免越界
{
pc->data[i] = pc->data[i + 1];
}
pc->sz--;//刪除完成后別忘了個數(shù)-1
printf("刪除成功\n");
}
//修改
void Modify(Contact* pc)
{
assert(pc);
char name[20] = { 0 };
printf("請輸入要修改的名字:");
scanf("%s", name);
int ret = FindByName(pc, name);
if (-1 == ret)
{
printf("查無此人\n");
return;
}
printf("請輸入名字:");
scanf("%s", pc->data[ret].name);
printf("請輸入年齡:");
scanf("%d", &(pc->data[ret].age));
printf("請輸入性別:");
scanf("%s", pc->data[ret].sex);
printf("請輸入地址:");
scanf("%s", pc->data[ret].addr);
printf("請輸入電話:");
scanf("%s", pc->data[ret].tele);
printf("修改成功\n");
}
//排序
int cmp(const void* e1, const void* e2)
{
return strcmp(((PeoInfo*)e1)->name, ((PeoInfo*)e2)->name);
}
void Order(Contact* pc)
{
assert(pc);
qsort(pc->data, pc->sz, sizeof(pc->data[0]), cmp);
printf("排序成功\n");
}
//保存
void SaveContact(Contact* pc)
{
//第一步打開文件
FILE* pf = fopen("contact.txt", "wb");
if (pf == NULL)
{
perror("fopen:");
}
else
{
//寫數(shù)據(jù),一個人一個人的寫
//data數(shù)組里一個元素就是一個結構體,也就是一個人
for (int i = 0; i < pc->sz; i++)
{
fwrite(pc->data + i, sizeof(PeoInfo), 1, pf);
}
fclose(pf);
pf = NULL;
printf("保存成功\n");
}
}
//加載通訊錄
void LoadContact(Contact* pc)
{
//打開文件
FILE*pf=fopen("contact.txt", "rb");
if (pf == NULL)
{
perror("LoadCContact:");
}
else
{
//讀取文件
PeoInfo tmp = { 0 };
int i = 0;
while (fread(&tmp, sizeof(PeoInfo), 1, pf))//一次讀一個人,如果讀取完畢返回0
{
//寫數(shù)據(jù)
//由于在退出時銷毀了通訊錄,所以回到初始大小,如果存儲的數(shù)據(jù)打于初始容量,需要擴容
check_capacity(pc);//檢查是否需要擴容,如果需要就擴容
pc->data[i] = tmp;
pc->sz++;
i++;
}
fclose(pf);
pf = NULL;
}
}
文章來源地址http://www.zghlxwxcb.cn/news/detail-803232.html
到了這里,關于通訊錄的實現(xiàn)(靜態(tài)版本,動態(tài)版本,文件版本)(后附完整源代碼)的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!