二.頭文件的詳細(xì)內(nèi)容準(zhǔn)備工作:
一.分模塊開(kāi)發(fā)
?1.test.c,實(shí)現(xiàn)模塊的測(cè)試環(huán)節(jié)
?2.contact.c,實(shí)現(xiàn)函數(shù)的功能
?3.contact.h,實(shí)現(xiàn)函數(shù)的命名與結(jié)構(gòu)體的使用
下面重點(diǎn)講解函數(shù)實(shí)現(xiàn)的函數(shù),在開(kāi)始時(shí)會(huì)提供頭文件,以便于提高本文的可讀性。
#include//printf,scanf,perror
#include//system,malloc,realloc
#include//strcmp
//對(duì)開(kāi)辟的大小,方便之后的統(tǒng)一修改。
enum SIZE
{NAME_SIZE=10,
SEX_SIZE=5,
TELE_SIZE=15,
ADDRE_SIZE=20,
DEFAULT_SIZE=2,
ADD_SIZE=2
};
//功能的選項(xiàng)數(shù)字賦予一定的意義
enum function
{ADD=1,
DEL,
FIND,
MODIFY,
PRINT,
SORT,
EXIT
};
//聯(lián)系人信息
typedef struct people
{char name[NAME_SIZE];
int age;
char sex[SEX_SIZE];
char tele[TELE_SIZE];
char addre[ADD_SIZE];
}peo;
//通訊錄信息
typedef struct Contact
{int count;//聯(lián)系人個(gè)數(shù)
int capacity;//當(dāng)前大容量
peo CON[];//柔性數(shù)組利用內(nèi)存池的概念,使內(nèi)存管理更加高效,并且free只要一次,更方便。
}contact;
//菜單
void menu();
//初始化通訊錄
void Init_contact(contact** p);//要修改一級(jí)指針?biāo)砸獋饕患?jí)指針的地址用二級(jí)指針來(lái)接收
//添加聯(lián)系人信息
void Add_Contact(contact** p);//同理
//打印通訊錄
void Print_Contact(contact* p);
//刪除聯(lián)系人信息
void Del_Contact(contact* p);
//查找聯(lián)系人信息
void Find_Contact(contact* p);
//修改聯(lián)系人信息
void Modify_Contact(contact* p);
//釋放已開(kāi)辟的內(nèi)存空間
void Distory_Contact(contact** p);//同理
//按照名字進(jìn)行排序通訊錄
void Sort_Contact(contact* p);
三.函數(shù)的實(shí)現(xiàn)
1.打印菜單void menu()
{printf("******************************************\n");
printf("******** 1.增加聯(lián)系人 2.刪除聯(lián)系人 *******\n");
printf("******** 3.查找聯(lián)系人 4.修改聯(lián)系人 *******\n");
printf("******** 5.打印聯(lián)系人 6.排序聯(lián)系人 *******\n");
printf("******** 7.退出通訊錄 *******\n");
printf("******************************************\n");
}
2.初始化通訊錄參數(shù)無(wú),返回類(lèi)型無(wú)(可以寫(xiě)return;)
void Init_contact(contact** p)
{*p = (contact*)malloc(4*2 + sizeof(peo) * DEFAULT_SIZE);
if (*p != NULL)
{(*p)->count = 0;
(*p)->capacity = DEFAULT_SIZE;
}
else
{perror("Init_contact");
return;
}
}
3.添加聯(lián)系人信息1.這里的開(kāi)辟空間默認(rèn)為兩個(gè)整形+初始能存的聯(lián)系人個(gè)數(shù)(2)
2.結(jié)構(gòu)體指針訪問(wèn)成員只能是一級(jí)指針,要改變一級(jí)指針,就得給函數(shù)傳二級(jí)指針
3.這里也可以用calloc,不過(guò)比較麻煩,并且效率比,malloc略低。
4.注意對(duì)開(kāi)辟空間返回的地址進(jìn)行檢查
void Add_Contact(contact** p)
{int judge = 0;
//判斷內(nèi)存是否夠
if ((*p)->count== (*p)->capacity)
{printf("通訊錄已滿,請(qǐng)確定是否要增容(1是0否):");
scanf("%d", &judge);
if (judge)
{ contact* ptr = (contact*)realloc(*p, 4 * 2 + sizeof(peo) * ((*p)->capacity+ ADD_SIZE));
if (ptr != NULL)
{ (*p) = ptr;
(*p)->capacity += ADD_SIZE;
printf("增容成功\n");
}
else
{ perror("Add_Contact");
printf("增容失敗\n");
return;
}
}
else
{ return;
}
}
//輸入信息部分
printf("請(qǐng)輸入姓名:");
scanf("%s", (*p)->CON[(*p)->count].name);
printf("請(qǐng)輸入年齡:");
scanf("%d", &(*p)->CON[(*p)->count].age);
printf("請(qǐng)輸入性別:");
scanf("%s", (*p)->CON[(*p)->count].sex);
printf("請(qǐng)輸入電話:");
scanf("%s", (*p)->CON[(*p)->count].tele);
printf("請(qǐng)輸入住址:");
scanf("%s", (*p)->CON[(*p)->count].addre);
printf("增加成功!\n");
(*p)->count++;
}
4.打印聯(lián)系人信息1.對(duì)realloc返回值進(jìn)行檢查,如果為空要及時(shí)的報(bào)錯(cuò)
2.在輸入信息之后要對(duì)聯(lián)系人個(gè)數(shù)進(jìn)行加1
3.輸入信息時(shí)要確定訪問(wèn)的成員的類(lèi)型,以確定是否取地址
補(bǔ)充:取地址數(shù)組名與數(shù)組名在進(jìn)行輸入的時(shí)候,效果相同,因?yàn)樗鼈兊臄?shù)值是相同的,但是意義不同。
void Print_Contact(contact* p)
{if (p->count == 0)
{printf("通訊錄為空!\n");
return;
}
printf("%-5s\t%3s\t%-3s\t%-12s\t%-20s\t\n", "姓名",
"年齡",
"性別",
"電話",
"住址");
int i = 0;
for (i = 0; i< p->count; i++)
{printf("%-5s\t%3d\t%-3s\t%-12s\t%-20s\t\n", p->CON[i].name,
p->CON[i].age,
p->CON[i].sex,
p->CON[i].tele,
p->CON[i].addre);
}
}
5.查找名字1.在通訊錄無(wú)信息時(shí),應(yīng)該及時(shí)的提醒。
2.注意下標(biāo)與聯(lián)系人信息的個(gè)數(shù)的關(guān)系
3.如果打印的內(nèi)容太長(zhǎng),建議要進(jìn)行換行,提高代碼的易讀性。
4.打印的時(shí)候需要對(duì)齊,要設(shè)置好格式進(jìn)行打印,這樣打印的內(nèi)容較為簡(jiǎn)潔美觀。
const int Find_By_name(contact* p,char*arr)
{int i = 0;
for (i = 0; i< p->count; i++)
{if (strcmp(p->CON[i].name, arr) == 0)
{ return i;
}
}
return -1;
}
6.刪除聯(lián)系人信息1.由于這個(gè)函數(shù)只服務(wù)于實(shí)現(xiàn)函數(shù)的模塊,所以加上const
2.strcmp比較兩個(gè)字符串,如果相等返回0
3.如果沒(méi)有字符串返回-1,如果找到則返回其下標(biāo)
4.這個(gè)函數(shù)是服務(wù)于查找聯(lián)系人,修改聯(lián)系人,刪除聯(lián)系人的
void Del_Contact(contact* p)
{char name[20] = {0 };
printf("請(qǐng)輸入要?jiǎng)h除的聯(lián)系人:");
scanf("%s", name);
int ret = Find_By_name(p, name);
if (ret!=-1)
{int i = 0;
for (i = ret; i< p->count-1; i++)
{ p->CON[ret] = p->CON[ret + 1];
}
p->count--;
printf("已刪除\n");
}
else
{printf("查無(wú)此人\n");
}
}
7.查找聯(lián)系人1.這里刪除的思路是進(jìn)行覆蓋,至于最后一個(gè)元素的情況,在聯(lián)系人個(gè)數(shù)減過(guò)之后再添加會(huì)進(jìn)行覆蓋。
2.注意這里的i的范圍,結(jié)合下面的代碼可知可能會(huì)發(fā)生數(shù)組越界的問(wèn)題,所以要減去1
3.結(jié)構(gòu)體數(shù)組的成員可以直接覆蓋前一個(gè)成員,跟數(shù)組的特性一樣
void Find_Contact(contact* p)
{char name[20] = {0 };
printf("請(qǐng)輸入要查找的聯(lián)系人:");
scanf("%s", name);
int ret = Find_By_name(p, name);
if (ret != -1)
{printf("%-5s\t%3s\t%-3s\t%-12s\t%-20s\t\n", "姓名",
"年齡",
"性別",
"電話",
"住址");
printf("%-5s\t%3d\t%-3s\t%-12s\t%-20s\t\n", p->CON[ret].name,
p->CON[ret].age,
p->CON[ret].sex,
p->CON[ret].tele,
p->CON[ret].addre);
}
else
{printf("查無(wú)此人\n");
}
}
8.修改聯(lián)系人信息void Modify_Contact(contact* p)
{char name[20] = {0 };
printf("請(qǐng)輸入要修改的聯(lián)系人:");
scanf("%s", name);
int ret = Find_By_name(p, name);
if (ret != -1)
{printf("請(qǐng)輸入姓名:");
scanf("%s", p->CON[ret].name);
printf("請(qǐng)輸入年齡:");
scanf("%d", &p->CON[ret].age);
printf("請(qǐng)輸入性別:");
scanf("%s", p->CON[ret].sex);
printf("請(qǐng)輸入電話:");
scanf("%s", p->CON[ret].tele);
printf("請(qǐng)輸入住址:");
scanf("%s", p->CON[ret].addre);
printf("修改成功!\n");
}
else
{printf("查無(wú)此人\n");
}
}
9.排序聯(lián)系人(按照名字)int my_cmp(const void* e1, const void* e2)
{return strcmp(((peo*)e1)->name, ((peo*)e2)->name);
}
void Sort_Contact(contact* p)
{qsort(p->CON, p->count, sizeof(peo), my_cmp);
printf("排序成功!\n");
}
四.總結(jié) 1.test.c1.快排要寫(xiě)一個(gè)比較函數(shù),由于是字符串比較要用到字符串比較函數(shù)
2.要注意快排的參數(shù)——排序的數(shù)組,排序的個(gè)數(shù),元素的大小,比較函數(shù)
#define _CRT_SECURE_NO_WARNINGS 1
#include"contact.h"
int main()
{contact *con =NULL;
Init_contact(&con);
int input = 0;
do
{menu();
printf("請(qǐng)輸入:");
scanf("%d", &input);
switch (input)
{case ADD:
system("cls");
Add_Contact(&con);
break;
case DEL:
system("cls");
Del_Contact(con);
break;
case FIND:
system("cls");
Find_Contact(con);
break;
case MODIFY:
system("cls");
Modify_Contact(con);
break;
case PRINT:
system("cls");
Print_Contact(con);
break;
case SORT:
system("cls");
Sort_Contact(con);
break;
case EXIT:
system("cls");
Distory_Contact(&con);
printf("退出成功\n");
break;
default:
printf("輸入錯(cuò)誤\n");
break;
}
} while (input!=EXIT);
return 0;
}
2.contact.c#define _CRT_SECURE_NO_WARNINGS 1
#include"contact.h"
void menu()
{printf("******************************************\n");
printf("******** 1.增加聯(lián)系人 2.刪除聯(lián)系人 *******\n");
printf("******** 3.查找聯(lián)系人 4.修改聯(lián)系人 *******\n");
printf("******** 5.打印聯(lián)系人 6.排序聯(lián)系人 *******\n");
printf("******** 7.退出通訊錄 *******\n");
printf("******************************************\n");
}
void Init_contact(contact** p)
{*p = malloc(4*2 + sizeof(peo) * DEFAULT_SIZE);
if (*p != NULL)
{(*p)->count = 0;
(*p)->capacity = DEFAULT_SIZE;
}
else
{perror("Init_contact");
return;
}
}
//const void Think_Capacity(contact** p)
//{//
// if ((*p)->count == (*p)->capacity)
// {// contact* ptr = (contact*)realloc(*p, 8 + sizeof(peo) * ((*p)->capacity + ADD_SIZE));
// if (ptr != NULL)
// {// (*p) = ptr;
// (*p)->capacity += ADD_SIZE;
// printf("增容成功\n");
// }
// else
// {// perror("Add_Contact");
// printf("增容失敗\n");
// return;
// }
// }
//
//}
//void Load_Contact(contact** p)
//{// FILE* pf = fopen("contact.txt", "rb");
// if (NULL == pf)
// {// perror("Load_Contact");
// }
// else
// {// peo tmp = { 0 };
// while (fread(&tmp, sizeof(peo), 1, pf))
// {// Think_Capacity(p);
// (*p)->CON[(*p)->count] = tmp;
// (*p)->count++;
// }
// }
// fclose(pf);
// pf = NULL;
//}
void Add_Contact(contact** p)
{int judge = 0;
if ((*p)->count== (*p)->capacity)
{printf("通訊錄已滿,請(qǐng)確定是否要增容(1是0否):");
scanf("%d", &judge);
if (judge)
{ contact* ptr = (contact*)realloc(*p, 4 * 2 + sizeof(peo) * ((*p)->capacity + ADD_SIZE));
if (ptr != NULL)
{ (*p) = ptr;
(*p)->capacity += ADD_SIZE;
printf("增容成功\n");
}
else
{ perror("Add_Contact");
printf("增容失敗\n");
return;
}
}
else
{ return;
}
}
printf("請(qǐng)輸入姓名:");
scanf("%s", (*p)->CON[(*p)->count].name);
printf("請(qǐng)輸入年齡:");
scanf("%d", &(*p)->CON[(*p)->count].age);
printf("請(qǐng)輸入性別:");
scanf("%s", (*p)->CON[(*p)->count].sex);
printf("請(qǐng)輸入電話:");
scanf("%s", (*p)->CON[(*p)->count].tele);
printf("請(qǐng)輸入住址:");
scanf("%s", (*p)->CON[(*p)->count].addre);
printf("增加成功!\n");
(*p)->count++;
}
void Print_Contact(contact* p)
{if (p->count == 0)
{printf("通訊錄為空!\n");
return;
}
printf("%-5s\t%3s\t%-3s\t%-12s\t%-20s\t\n", "姓名", "年齡", "性別", "電話", "住址");
int i = 0;
for (i = 0; i< p->count; i++)
{printf("%-5s\t%3d\t%-3s\t%-12s\t%-20s\t\n", p->CON[i].name,
p->CON[i].age,
p->CON[i].sex,
p->CON[i].tele,
p->CON[i].addre);
}
}
const int Find_By_name(contact* p,char*arr)
{int i = 0;
for (i = 0; i< p->count; i++)
{if (strcmp(p->CON[i].name, arr) == 0)
{ return i;
}
}
return -1;
}
void Del_Contact(contact* p)
{char name[20] = {0 };
printf("請(qǐng)輸入要?jiǎng)h除的聯(lián)系人:");
scanf("%s", name);
int ret = Find_By_name(p, name);
if (ret!=-1)
{int i = 0;
for (i = ret; i< p->count-1; i++)
{ p->CON[ret] = p->CON[ret + 1];
}
p->count--;
printf("已刪除\n");
}
else
{printf("查無(wú)此人\n");
}
}
void Find_Contact(contact* p)
{char name[20] = {0 };
printf("請(qǐng)輸入要查找的聯(lián)系人:");
scanf("%s", name);
int ret = Find_By_name(p, name);
if (ret != -1)
{printf("%-5s\t%3s\t%-3s\t%-12s\t%-20s\t\n", "姓名", "年齡", "性別", "電話", "住址");
printf("%-5s\t%3d\t%-3s\t%-12s\t%-20s\t\n", p->CON[ret].name, p->CON[ret].age,
p->CON[ret].sex, p->CON[ret].tele,
p->CON[ret].addre);
}
else
{printf("查無(wú)此人\n");
}
}
void Modify_Contact(contact* p)
{char name[20] = {0 };
printf("請(qǐng)輸入要修改的聯(lián)系人:");
scanf("%s", name);
int ret = Find_By_name(p, name);
if (ret != -1)
{printf("請(qǐng)輸入姓名:");
scanf("%s", p->CON[ret].name);
printf("請(qǐng)輸入年齡:");
scanf("%d", &p->CON[ret].age);
printf("請(qǐng)輸入性別:");
scanf("%s", p->CON[ret].sex);
printf("請(qǐng)輸入電話:");
scanf("%s", p->CON[ret].tele);
printf("請(qǐng)輸入住址:");
scanf("%s", p->CON[ret].addre);
printf("修改成功!\n");
}
else
{printf("查無(wú)此人\n");
}
}
//void Save_Contact(contact* p)
//{// FILE* pf = fopen("contact.txt", "wb");
// if (NULL == pf)
// {// perror("Save_Contact:pf");
// }
// else
// {// int i = 0;
// for (i = 0; i< p->count; i++)
// {// fwrite(p->CON + i, sizeof(peo), 1, pf);
// }
// }
// printf("保存成功!\n");
// fclose(pf);
// pf = NULL;
//
//}
void Distory_Contact(contact** p)
{free(*p);
*p = NULL;
}
int my_cmp(const void* e1, const void* e2)
{return strcmp(((peo*)e1)->name, ((peo*)e2)->name);
}
void Sort_Contact(contact* p)
{qsort(p->CON, p->count, sizeof(peo), my_cmp);
printf("排序成功!\n");
}
3.contact.h#include//printf,scanf,perror
#include//system,malloc,realloc
#include//strcmp
//對(duì)開(kāi)辟的大小,方便之后的統(tǒng)一修改。
enum SIZE
{NAME_SIZE=10,
SEX_SIZE=5,
TELE_SIZE=15,
ADDRE_SIZE=20,
DEFAULT_SIZE=2,
ADD_SIZE=2
};
//功能的選項(xiàng)數(shù)字賦予一定的意義
enum function
{ADD=1,
DEL,
FIND,
MODIFY,
PRINT,
SORT,
EXIT
};
//聯(lián)系人信息
typedef struct people
{char name[NAME_SIZE];
int age;
char sex[SEX_SIZE];
char tele[TELE_SIZE];
char addre[ADD_SIZE];
}peo;
//通訊錄信息
typedef struct Contact
{int count;//聯(lián)系人個(gè)數(shù)
int capacity;//當(dāng)前大容量
peo CON[];//柔性數(shù)組利用內(nèi)存池的概念,使內(nèi)存管理更加高效,并且free只要一次,更方便。
}contact;
//菜單
void menu();
//初始化通訊錄
void Init_contact(contact** p);//要修改一級(jí)指針?biāo)砸獋饕患?jí)指針的地址用二級(jí)指針來(lái)接收
//添加聯(lián)系人信息
void Add_Contact(contact** p);//同理
//打印通訊錄
void Print_Contact(contact* p);
//刪除聯(lián)系人信息
void Del_Contact(contact* p);
//查找聯(lián)系人信息
void Find_Contact(contact* p);
//修改聯(lián)系人信息
void Modify_Contact(contact* p);
//釋放已開(kāi)辟的內(nèi)存空間
void Distory_Contact(contact** p);//同理
//按照名字進(jìn)行排序通訊錄
void Sort_Contact(contact* p);
//保存通訊錄信息
//void Save_Contact(contact* p);
//加載通訊錄信息
//void Load_Contact(contact* p);
五.文件操作所需的函數(shù)
1.檢查容量const void Think_Capacity(contact** p)
{if ((*p)->count == (*p)->capacity)
{contact* ptr = (contact*)realloc(*p, 8 + sizeof(peo) * ((*p)->capacity + ADD_SIZE));
if (ptr != NULL)
{ (*p) = ptr;
(*p)->capacity += ADD_SIZE;
printf("增容成功\n");
}
else
{ perror("Add_Contact");
printf("增容失敗\n");
return;
}
}
}
2.添加聯(lián)系人信息void Load_Contact(contact** p)
{FILE* pf = fopen("contact.txt", "rb");
if (NULL == pf)
{perror("Load_Contact");
}
else
{peo tmp = {0 };
while (fread(&tmp, sizeof(peo), 1, pf))
{ Think_Capacity(p);
(*p)->CON[(*p)->count] = tmp;
(*p)->count++;
}
}
fclose(pf);
pf = NULL;
}
3.保存聯(lián)系人信息void Save_Contact(contact* p)
{FILE* pf = fopen("contact.txt", "wb");
if (NULL == pf)
{perror("Save_Contact:pf");
}
else
{int i = 0;
for (i = 0; i< p->count; i++)
{ fwrite(p->CON + i, sizeof(peo), 1, pf);
}
}
printf("保存成功!\n");
fclose(pf);
pf = NULL;
}
要在當(dāng)前項(xiàng)目(與源文件同路徑)里面創(chuàng)建一個(gè):contact.txt
你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機(jī)房具備T級(jí)流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級(jí)服務(wù)器適合批量采購(gòu),新人活動(dòng)首月15元起,快前往官網(wǎng)查看詳情吧
網(wǎng)站標(biāo)題:【進(jìn)階C語(yǔ)言】通訊錄(完整版)-創(chuàng)新互聯(lián)
文章起源:http://www.rwnh.cn/article26/dghgcg.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供品牌網(wǎng)站設(shè)計(jì)、企業(yè)網(wǎng)站制作、網(wǎng)站收錄、微信小程序、網(wǎng)站設(shè)計(jì)公司、云服務(wù)器
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容