test.c
測試
contact.c
實(shí)現(xiàn)函數(shù)功能
功能:
2 靜態(tài)數(shù)組方式 2.1. 測試程序
- 存放1000個(gè)好友的信息
- 姓名
- 電話
- 性別
- 住址
- 年齡
- 增加好友信息
- 刪除指定名字的信息
- 查找好友信息
- 修改好友信息
- 打印好友信息
- 排序…
int main()
{int input = 0;
//int size = 0; // 記錄通訊錄有多少個(gè)記錄
// 創(chuàng)建通訊錄
// 好友信息結(jié)構(gòu)體存放在 contact.h 中
Contact con; // 存放1000個(gè)人的信息,和size
// 初始換通訊錄
initContact(&con);
//
do
{menu();
printf("please choose command number\n");
scanf("%d", &input);
switch (input)
{ case ADD:
addContactor(&con);
showContact(&con);
break;
case DEL:
deleteContact(&con);
showContact(&con);
break;
case SEARCH:
searchContact(&con);
break;
case MODIFY:
modifyContact(&con);
break;
case SHOW:
showContact(&con);
break;
case EXIT:
printf("exit the contact\n");
break;
default:
printf("you have the wrong choose number, please choose again\n");
break;
}
} while (input);
}
2.2 創(chuàng)建的結(jié)構(gòu)體和枚舉類//contact.h
#define MAX 1000
#define MAX_NAME 20
#define MAX_SEX 5
#define MAX_TELE 12
#define MAX_ADDR 50
// 在菜單欄進(jìn)行選擇的時(shí)候,如果使用switch case
// case這里跟上1,2,3,4...這些數(shù)字,對(duì)程序員不友好
// 想要知道數(shù)字是哪種操作,還要看一眼菜單對(duì)應(yīng)的操作是什么,不如使用枚舉類
enum Option
{EXIT,
ADD,
DEL,
SEARCH,
MODIFY,
SHOW
};
// 聯(lián)系人信息
typedef struct PeoInfo
{char name[MAX_NAME];
int age;
char sex[MAX_SEX];
char tele[MAX_TELE];
char addr[MAX_ADDR];
}PeoInfo;
// 通訊錄
typedef struct Contact
{int size; // 記錄當(dāng)前元素個(gè)數(shù)
PeoInfo data[MAX]; // 存放1000個(gè)信息
}Contact;
2.3. 通訊錄初始化// contact.h
// 初始化通訊錄
void initContact(Contact* pcon);
// contact.c
void initContact(Contact* pcon)
{memset(pcon->data, 0, sizeof(pcon->data));
pcon->size = 0; // 設(shè)置通訊錄最初是 0 個(gè)元素
}
2.4. 菜單功能//test.c
void menu()
{printf("********************************************\n");
printf("*******************通訊錄********************\n");
printf("***********1、add 2、del *********\n");
printf("***********3、search 4、modify *********\n");
printf("***********5、show 0、exit *********\n");
printf("********************************************\n");
printf("********************************************\n");
}
2.5. 添加聯(lián)系人// contact.h
// 添加聯(lián)系人
// 添加失敗返回0,添加成功返回1
int addContactor(Contact* pcon);
// contact.c
int addContactor(Contact* pcon)
{int size = pcon->size;
if (size == MAX )
{printf("通訊錄已滿,添加失敗...\n");
return 0;
}
printf("please input the name of your friend\n");
scanf("%s", pcon->data[size].name);
printf("please input the tele of your friend\n");
scanf("%s", pcon->data[size].tele);
printf("please input the age of your friend\n");
scanf("%d", &(pcon->data[size].age));
printf("please input the sex of your friend\n");
scanf("%s", pcon->data[size].sex);
printf("please input the addr of your friend\n");
scanf("%s", pcon->data[size].addr);
pcon->size = size + 1;
printf("添加成功...\n");
return 1;
}
2.6. 查找聯(lián)系人// contact.h
// 查找聯(lián)系人
int searchContact(Contact* con);
// 查找指定姓名的聯(lián)系人
// 返回下標(biāo),未找到返回-1
// 給函數(shù)或者全局變量加上 static 時(shí),只能自己所在原文件有效。
static int searchContactByName(Contact* con, char name[]);
//contact.c
static int searchContactByName(Contact* con, char name[]) // 給函數(shù)或者全局變量加上 static 時(shí),只能自己所在原文件有效。
{for (int i = 0; i< con->size; i++)
{if (strcmp(con->data[i].name, name) == 0)
{ return i;
}
}
return -1;
}
int searchContact(Contact* con)
{int size = con->size;
char searchName[MAX_NAME] = {0};
int index = -1;
if (size == 0)
{printf("the contact is empty...\n");
return 0;
}
printf("請(qǐng)輸入要查找的姓名>\n");
scanf("%s", searchName);
index = searchContactByName(con, searchName);
if (index == -1)
{printf("未查找到姓名為[%s]的聯(lián)系人\n", searchName);
return 0;
}
printf("該聯(lián)系人的信息為>\n");
showContactByIndex(con, index);
return 1;
}
2.7. 顯示全部聯(lián)系人和顯示指定索引處的聯(lián)系人// contact.h
// 顯示通訊錄
void showContact(const Contact* pcon);
// 顯示指定索引處聯(lián)系人的信息
void showContactByIndex(const Contact* pcon, int index);
// contact.c
void showContact(const Contact* pcon)
{int size = pcon->size;
if (size == 0)
{printf("the info of contact is null\n");
return;
}
printf("the info of contact is...\n");
printf("%-4s\t%-20s\t%-12s\t%-4s\t%-5s\t%-50s \n", "序號(hào)", "姓名", "電話", "年齡", "性別", "地址");
for (int i = 0; i< size; i++)
{
printf("%-4d\t%-20s\t%-12s\t%-4d\t%-5s\t%-50s \n",
i,
pcon->data[i].name,
pcon->data[i].tele,
pcon->data[i].age,
pcon->data[i].sex,
pcon->data[i].addr);
}
printf("end...\n");
}
void showContactByIndex(const Contact* pcon, int index)
{if (index >= pcon->size)
{printf("索引超出范圍...\n");
return;
}
printf("%-4s\t%-20s\t%-12s\t%-4s\t%-5s\t%-50s \n", "序號(hào)", "姓名", "電話", "年齡", "性別", "地址");
printf("%-4d\t%-20s\t%-12s\t%-4d\t%-5s\t%-50s \n",
index,
pcon->data[index].name,
pcon->data[index].tele,
pcon->data[index].age,
pcon->data[index].sex,
pcon->data[index].addr);
}
2.8. 刪除聯(lián)系人//contact.h
int deleteContact(Contact* con);
//contact,c
int deleteContact(Contact* con)
{int size = con->size;
int index = -1; // 定義要?jiǎng)h除姓名的下標(biāo)
char deleteName[MAX_NAME] = {0};
char delConfirm = 0; // 確認(rèn)是否刪除
if (size == 0)
{printf("the contact is empty, you can't delete...\n");
return 0;
}
printf("please input the name you need to delete>\n");
scanf("%s", deleteName);
index = searchContactByName(con, deleteName);
if (index == -1)
{printf("未找到姓名為\"%s\"的聯(lián)系人\n", deleteName);
return 0;
}
while (1)
{printf("你確定刪除姓名為\"%s\"的聯(lián)系人嗎?y/n\n", deleteName);
scanf("%c", &delConfirm);
if (delConfirm == 'y' || delConfirm == 'Y')
{ // 確認(rèn)刪除
for (int i = index + 1; i< size; i++)
{ con->data[i - 1] = con->data[i];
}
con->size--;
printf("刪除成功!\n");
return 1;
}
if (delConfirm == 'n' || delConfirm == 'N')
{ // 取消刪除
return 0;
}
printf("請(qǐng)輸入正確的指令\n");
}
return 0;
}
2.9. 修改聯(lián)系人// contact.h
int modifyContact(Contact* con);
//contact.c
int modifyContact(Contact* con)
{char modifyName[MAX_NAME];
int index = -1;
if (con->size == 0)
{printf("contact is empty...\n");
return 0;
}
printf("需要修改的聯(lián)系人姓名:\n");
scanf("%s", modifyName);
index = searchContactByName(con, modifyName);
if (index == -1)
{printf("通訊錄沒有姓名為【%s】的人\n", modifyName);
return 0;
}
printf("該聯(lián)系人的信息為>\n");
showContactByIndex(con, index);
printf("請(qǐng)輸入要修改的信息>\n");
printf("please input the name of your friend\n");
scanf("%s", con->data[index].name);
printf("please input the tele of your friend\n");
scanf("%s", con->data[index].tele);
printf("please input the age of your friend\n");
scanf("%d", &(con->data[index].age));
printf("please input the sex of your friend\n");
scanf("%s", con->data[index].sex);
printf("please input the addr of your friend\n");
scanf("%s", con->data[index].addr);
printf("***********修改成功***********\n");
printf("修改后的聯(lián)系人信息為>\n");
showContactByIndex(con, index);
return 1;
}
3 動(dòng)態(tài)申請(qǐng)內(nèi)存方式上面寫的通訊錄,上來就能存放1000個(gè)人的信息,如果多了少了對(duì)內(nèi)存都不友好。
那我們就可以設(shè)計(jì),比如默認(rèn)可以存放10個(gè)人的信息,當(dāng)發(fā)現(xiàn)通訊錄滿的時(shí)候,我們進(jìn)行動(dòng)態(tài)的擴(kuò)容。每次增加5個(gè)人的空間等等:10 15 20 25...
typedef struct Contact
{//Info data[MAX];
Info* data;
int size;
int capacity; // 通訊錄的大容量,當(dāng)size和這個(gè)一樣大時(shí),我們進(jìn)行擴(kuò)容
}Contact;
我們給通訊錄初始化時(shí),是創(chuàng)建一個(gè)有10個(gè)人信息的空間,當(dāng)容量達(dá)到10個(gè)時(shí),我們進(jìn)行擴(kuò)容。
所以,除了需要記錄通訊錄當(dāng)前包含聯(lián)系人的個(gè)數(shù)之外,還要記錄當(dāng)前通訊錄的容量,這一點(diǎn)在靜態(tài)數(shù)組中沒有記錄的原因,是靜態(tài)數(shù)組已經(jīng)規(guī)定了大容量,這個(gè)值我們是已知的
3.2. 初始化通訊錄初始化時(shí),我們可以默認(rèn)是10,也可以默認(rèn)是1,2,3,4,5等等任意的數(shù)字,所以我們可以在contact.h
中定義
#define DEFALUT_CAPACITY 10
void initContact(Contact* pcon)
{//memset(pcon->data, 0, sizeof(pcon->data));
pcon->data = (PeoInfo*)malloc(DEFAULT_CAPACITY * sizeof(PeoInfo));
if (pcon->data == NULL)
{return;
}
pcon->size = 0; // 設(shè)置通訊錄最初是 0 個(gè)元素
pcon->capacity = DEFAULT_CAPACITY;
}
3.3. 增加聯(lián)系人通訊錄滿的時(shí)候,原來是不能增加,現(xiàn)在是擴(kuò)容
仍然在contact.h中定義默認(rèn)的擴(kuò)容個(gè)數(shù)
#define EXTEND_CAPACITY 5
int addContactor(Contact* pcon)
{int size = pcon->size;
// 判斷通訊錄容量是否滿了
// 如果滿了,就擴(kuò)容,擴(kuò)容完繼續(xù)執(zhí)行添加
// 如果不滿,就繼續(xù)添加
if (contactIsFull(pcon))
{// 擴(kuò)容
PeoInfo* ptemp = (PeoInfo*)realloc(pcon->data, (pcon->capacity + EXTEND_CAPACITY) * sizeof(PeoInfo));
if (ptemp == NULL)
{ printf("添加失敗\n");
return 0;
}
pcon->data = ptemp;
pcon->capacity += 2;
printf("擴(kuò)容成功\n");
return 1;
}
printf("please input the name of your friend\n");
scanf("%s", pcon->data[size].name);
printf("please input the tele of your friend\n");
scanf("%s", pcon->data[size].tele);
printf("please input the age of your friend\n");
scanf("%d", &(pcon->data[size].age));
printf("please input the sex of your friend\n");
scanf("%s", pcon->data[size].sex);
printf("please input the addr of your friend\n");
scanf("%s", pcon->data[size].addr);
pcon->size = size + 1;
printf("添加成功...\n");
return 1;
}
// 這里面涉及到一個(gè)contactIsFull函數(shù),是用來判斷當(dāng)前通訊錄是否為滿的
// 聲明在 contact.h中
static int contactIsFull(const Contact* pcon);
// 定義在contact.c
static int contactIsFull(const Contact* pcon)
{if (pcon->size == pcon->capacity)
{return 1;
}
return 0;
}
3.4. 刪除/修改/查找聯(lián)系人不需要修改,因?yàn)閿U(kuò)容完了之后,再刪除,只是移動(dòng) size 這個(gè)標(biāo)記,并把原來的內(nèi)容往前移動(dòng),并不涉及內(nèi)存的回收。
3.5. 退出(銷毀內(nèi)存空間)銷毀通訊錄,釋放動(dòng)態(tài)申請(qǐng)的內(nèi)存空間
//contact.h
// 釋放內(nèi)存空間
void destroyContact(Contact* pcon);
//contact.c
// 釋放內(nèi)存空間
void destroyContact(Contact* pcon)
{free(pcon->data);
pcon->data = NULL;
}
4 文件版本的通訊錄之前的版本,是都放在內(nèi)存中的,當(dāng)程序結(jié)束運(yùn)行時(shí),通訊錄就會(huì)銷毀了。
我們現(xiàn)在把通訊錄持久化到文件中去。
我們可以新增一個(gè)保存save
函數(shù)。
void menu()
{printf("********************************************\n");
printf("*******************通訊錄********************\n");
printf("***********1、add 2、del *********\n");
printf("***********3、search 4、modify *********\n");
printf("***********5、show 6、save *********\n");
printf("*********** 0、xeit *********\n");
printf("********************************************\n");
}
所以在枚舉類和測試函數(shù)的switch case中,也要加上
enum Option
{EXIT,
ADD,
DEL,
SEARCH,
MODIFY,
SHOW,
SAVE
};
4.2. 添加保存到文件的操作case SAVE:
saveContact(&con);
break;
case EXIT:
// 銷毀通訊錄,釋放動(dòng)態(tài)申請(qǐng)的內(nèi)存空間
// 退出銷毀之前,最好是也要保存一下通訊錄
saveContact(&con);
destroyContact(&con);
printf("exit the contact\n");
break;
// contact.h
// 保存文件
void saveContact(Contact* pcon);
// contact.c
// 保存文件
void saveContact(Contact* pcon)
{FILE* pfWrite = fopen("contact.txt", "wb");
if (pfWrite == NULL)
{printf("saveContact::%s\n", strerror(errno));
}
if (pcon->size == 0)
{printf("通訊錄為空...\n");
return;
}
//fprintf(pfWrite,"%-4s\t%-20s\t%-12s\t%-4s\t%-5s\t%-50s \n", "序號(hào)", "姓名", "電話", "年齡", "性別", "地址");
for (int i = 0; i< pcon->size; i++)
{fwrite(&(pcon->data[i]), sizeof(PeoInfo), 1, pfWrite);
}
//fprintf(pfWrite ,"end...\n");
fclose(pfWrite);
pfWrite = NULL;
}
4.3. 初始化通訊錄初始化通訊錄時(shí),我們最好是把保存在文件中的數(shù)據(jù),讀入到內(nèi)存中,這樣才更合理
void initContact(Contact* pcon)
{ //memset(pcon->data, 0, sizeof(pcon->data));
pcon->data = (PeoInfo*)malloc(DEFAULT_CAPACITY * sizeof(PeoInfo));
if (pcon->data == NULL)
{return;
}
pcon->size = 0; // 設(shè)置通訊錄最初是 0 個(gè)元素
pcon->capacity = DEFAULT_CAPACITY;
// 把文件加載到通訊錄中
loadContact(pcon);
}
// 其中 loadContact 在 contact.h中聲明
// 在 contact.c 中定義
// 加載文件中的信息到通訊錄中
void loadContact(Contact* pcon)
{FILE* pfRead = fopen("contact.txt", "rb");
PeoInfo tmp = {0};
if (pfRead == NULL)
{printf("loadContact::%s\n", strerror(errno));
return;
}
while (fread(&tmp,sizeof(PeoInfo),1,pfRead)) // 讀取的返回值,是實(shí)際讀取到的元素個(gè)數(shù),如果沒有讀到,就說明是返回0
{pcon->data[pcon->size] = tmp;
pcon->size++;
if (contactIsFull(pcon))
{ // 擴(kuò)容
PeoInfo* ptemp = (PeoInfo*)realloc(pcon->data, (pcon->capacity + EXTEND_CAPACITY) * sizeof(PeoInfo));
if (ptemp == NULL)
{ printf("添加失敗\n");
return 0;
}
pcon->data = ptemp;
pcon->capacity += 2;
//printf("擴(kuò)容成功\n");
}
}
// 關(guān)閉文件
fclose(pfRead);
pfRead = NULL;
}
你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機(jī)房具備T級(jí)流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級(jí)服務(wù)器適合批量采購,新人活動(dòng)首月15元起,快前往官網(wǎng)查看詳情吧