C語言實現(xiàn)通訊錄功能的流程與代碼
用C語言制作一個擁有添加,刪除,查找,修改,排序,清空,打印功能的通訊錄
用分模塊的方法來實現(xiàn)這個通訊錄,函數(shù)的聲明,類型的聲明放在一個.h文件中,函數(shù)的實現(xiàn)放在一個.c文件中,在主文件中來調(diào)用函數(shù)。
首先創(chuàng)建一個test.c文件用來測試并且實現(xiàn)通訊錄的功能

通訊錄需要顯示一個菜單來讓用戶具體選擇哪個功能,那么在test.c文件中就需要打印出來一個菜單,如下代碼:
#include <stdio.h>
void menu()
{
printf("***********************************\n");
printf("****** 1.add 2.del ******\n");
printf("****** 3.search 4.modify ******\n");
printf("****** 5.sort 6.empty ******\n");
printf("****** 7.print 0.exit ******\n");
printf("***********************************\n");
}
int main()
{
//通訊錄:1.add 2.del 3.search 4,modify 5.sort 6.empty 7.print 0.exit
do
{
menu();
} while (0);
return 0;
}接著就要讓用戶選擇輸入某個數(shù)組來使用通訊錄的功能,這時就可以用一個switch開關(guān)來實現(xiàn)了,如下代碼:
int input = 0;
do
{
menu();
printf("請選擇功能>:");
scanf("%d", &input);
switch (input)
{
case 1:
break;
case 2:
break;
case 3:
break;
case 4:
break;
case 5:
break;
case 6:
break;
case 7:
break;
case 0:
break;
default:
printf("請重新輸入\n");
break;
}
} while (input);在while循環(huán)的條件判斷部分直接寫input,這樣選擇輸入0的時候就直接跳出循環(huán)了,輸入其他數(shù)字可以繼續(xù)使用通訊錄的功能。
case后面跟著的都是數(shù)字,有時候調(diào)試代碼的時候比較容易忘記這個數(shù)字表示的是什么意思,所以這個時候可以用創(chuàng)建一個枚舉類型來定義對應(yīng)的枚舉常量。
創(chuàng)建一個contact.h文件來放類型的定義,函數(shù)的聲明。

然后把枚舉類型在里面進行聲明
enum input
{
Exit,
add,
sub,
search,
modify,
sort,
empty,
print
};之后要在主文件中調(diào)用這個頭文件
#include "contact.h"
同時可以把#include <stdio.h>這些庫函數(shù)的引用都放到contact.h這個文件當(dāng)中,這樣要引用新的庫函數(shù)時只需要在contact.h這個文件中添加就可以了。
這樣switch開關(guān)中的代碼就可以改成這樣了:
switch (input)
{
case add:
break;
case sub:
break;
case search:
break;
case modify:
break;
case sort:
break;
case empty:
break;
case print:
break;
case Exit:
break;
}然后開始用函數(shù)去實現(xiàn)每一個函數(shù)的功能,首先是添加功能,在添加之前,還得需要一個空的通訊錄,來存放添加進去的通訊人的數(shù)據(jù),而通訊人的數(shù)據(jù)有姓名,年齡,性別,電話號碼,地址這些數(shù)據(jù),都是一些不同類型的值,這時可以聲明一個結(jié)構(gòu)體類型來包含這些成員
好,切到contact.h文件來聲明一個結(jié)構(gòu)體類型:
typedef struct People
{
char name[20];
int age;
char sex[5];
char phone[20];
char address[30];
} People;同時還對這個類型重命名了一下,方便后續(xù)使用這個結(jié)構(gòu)體類型,這是需要考慮到通訊錄存放數(shù)據(jù)多少的問題,如果address里面存放的內(nèi)容放不下了,這是就需要對數(shù)組的大小進行更改,那這時就要先找到這個結(jié)構(gòu)體類型才能更改了,如果代碼寫的比較多的話就會比較亂,所以可以用#define定義的標(biāo)識符常量來定義這些值,以后要改的話就只需要找到#define就可以了
如下代碼:
#define NameMax 20 #define SexMax 5 #define PhoneMax 20 #define AddressMax 30
typedef struct People
{
char name[NameMax];
int age;
char sex[SexMax];
char phone[PhoneMax];
char address[AddressMax];
} People;因為這里是不同類型的值的定義,所以用#define來定義而不用枚舉類型來定義,因為枚舉類型是用來列舉相同類型的值的,比如前面的通訊錄功能都是屬于通訊錄的功能一類的值
下一步,通訊錄不只存放一個人的數(shù)據(jù),所以需要用這個結(jié)構(gòu)體類型來創(chuàng)建一個數(shù)組,假設(shè)這個通訊錄可以存放1000個人的數(shù)據(jù),同時還能記錄其中已存放了多少個人
那么可以在主函數(shù)中這么寫:
int main()
{
//通訊錄:1.add 2.del 3.search 4,modify 5.sort 6.empty 7.print 0.exit
People contact[1000];
int num;對于這個通訊錄和這個通訊人的數(shù)量,這兩個變量可以兩者之間是由聯(lián)系的,那么此時就可以再聲明一個結(jié)構(gòu)體類型來包含這兩個成員。
切到contact.h文件:
typedef struct Contact
{
People people[1000];
int num;
} Contact;聲明好這個通訊錄類型之后,需要在主文件中用這個類型創(chuàng)建一個變量,同時對變量的內(nèi)容進行初始化
int main()
{
//通訊錄:1.add 2.del 3.search 4,modify 5.sort 6.empty 7.print 0.exit
Contact contact;
InitialContact(&contact);切到contact.h文件聲明函數(shù):
//函數(shù)的聲明 //通訊錄初始化 void InitialContact(Contact* pc);
此時創(chuàng)建一個contact.c文件來實現(xiàn)函數(shù)的內(nèi)容:

切到contact.c文件:
#include "contact.h"
void InitialContact(Contact* pc)
{
memset(pc, 0, sizeof(*pc));
}要記得引這個contact.h頭文件
在對通訊錄的內(nèi)容進行完初始化之后,可以開始往里面添加通訊人的信息了,再聲明一個函數(shù):
test.c:
case add:
printf("添加通訊人\n");
AddPeople(&contact);
break;contact.h:
//添加通訊人 void AddPeople(Contact* pc);
contact.c:
void AddPeople(Contact* pc)
{
if (pc->num == 1000)
{
printf("通訊錄已滿\n");
return;
}
printf("請輸入姓名>:");
scanf("%s", pc->people[pc->num].name);
printf("請輸入年齡>:");
scanf("%d", &pc->people[pc->num].age);
printf("請輸入性別>:");
scanf("%s", pc->people[pc->num].sex);
printf("請輸入電話>:");
scanf("%s", pc->people[pc->num].phone);
printf("請輸入地址>:");
scanf("%s", pc->people[pc->num].address);
pc->num++;
}輸入完成之后,要記得讓通訊人數(shù)量+1
接下來可以嘗試顯示一下通訊錄中的通訊人信息了
contact.h:
//顯示通訊人信息 void PrintContact(const Contact* pc);
contact.c:
void PrintContact(const Contact* pc)
{
printf("%-20s %-20s %-20s %-20s %-20s\n", "姓名", "年齡", "性別", "電話", "地址");
int i = 0;
for (i = 0; i < pc->num; i++)
{
printf("%-20s %-20d %-20s %-20s %-20s\n", pc->people[i].name, pc->people[i].age, pc->people[i].sex, pc->people[i].phone, pc->people[i].address);
}
}在前面打印個通訊人列表修飾一下
test.c:
case print:
printf("顯示通訊人信息\n");
PrintContact(&contact);
break;接下來,開始實現(xiàn)通訊錄的刪除功能:
可以通過讓用戶輸入某個人的名字來刪除這個人在通訊錄中的信息,刪除功能的實現(xiàn)分為兩步,第一步,是需要找到這個人,第二步,刪除這個人在通訊錄中的信息
contact.h:
//刪除通訊人信息 void SubPeople(Contact* pc);
contact.c:
int FindByName(Contact* pc, const char* name)
{
//遍歷每一個contact結(jié)構(gòu)體中people數(shù)組成員中的已存放數(shù)據(jù)的每一個結(jié)構(gòu)體
int i = 0;
for (i = 0; i < sizeof(pc->num); i++)
{
if (strcmp(pc->people[i].name, name) == 0)
{
return i;//找到了返回對應(yīng)結(jié)構(gòu)體的下標(biāo)
}
}
return -1;//找不到就返回-1
}
void SubPeople(Contact* pc)
{
if (pc->num == 0)//先判斷通訊錄中有無存儲信息
{
printf("通訊錄已清空\n");
return;
}
//1.找到
printf("請輸入要刪除的人的姓名;>");
char name[NameMax];
scanf("%s", name);
int ret = FindByName(pc, name);//用以接收放回的數(shù)組下標(biāo)
if (ret == -1)
{
printf("找不到要刪除的人\n");
return;//讓函數(shù)直接返回
}
//2.刪除
//從找到的那個下標(biāo)位置開始,后面的數(shù)組元素(通訊人結(jié)構(gòu)體)依次往前賦值
int j = 0;
for (j = ret; j < pc->num - 1; j++)
{
pc->people[j] = pc->people[j + 1];
}
printf("刪除成功\n");
pc->num--;//通訊人數(shù)量-1
}test.c:
case sub: SubPeople(&contact); break;
每完成一個功能,都要去嘗試運行一下,看有沒有bug,否則最后才去找bug可能會比較麻煩。
在刪除功能中,用到了一個自己寫的FindByName函數(shù),然后在接下來的通訊錄查找功能實現(xiàn)中,同樣也要依賴這個函數(shù),不僅如此,在通訊錄修改功能中,也要用到這個函數(shù),而這個函數(shù)的實現(xiàn)是為了刪除、查找和修改功能而聲明的,所以可以不用寫在contact.h頭文件中進行聲明。
下面,來開始實現(xiàn)查找功能:
contact.h:
//查找通訊人 void SearchPeople(const Contact* pc);
contact.c:
void SearchPeople(const Contact* pc)
{
//查找
printf("請輸入要查找的人的姓名;>");
char name[NameMax];
scanf("%s", name);
int ret = FindByName(pc, name);//用以接收放回的數(shù)組下標(biāo)
if (ret == -1)
{
printf("找不到要查找的人\n");
return;//讓函數(shù)直接返回
}
//顯示
printf("%-20s %-20s %-20s %-20s %-20s\n", "姓名", "年齡", "性別", "電話", "地址");
printf("%-20s %-20d %-20s %-20s %-20s\n", pc->people[ret].name, pc->people[ret].age, pc->people[ret].sex, pc->people[ret].phone, pc->people[ret].address);
}test.c:
case search: SearchPeople(&contact); break;
查找功能已經(jīng)實現(xiàn)了,接下來就要實現(xiàn)修改功能了,先通過通訊人的姓名找到需要修改的結(jié)構(gòu)體對應(yīng)的下標(biāo),然后重新對這個結(jié)構(gòu)體進行賦值就可以了
contact.h:
//修改通訊人信息 void ModifyPeople(Contact* pc);
contact.c:
void ModifyPeople(Contact* pc)
{
//查找
printf("請輸入要修改的人的姓名;>");
char name[NameMax];
scanf("%s", name);
int ret = FindByName(pc, name);//用以接收放回的數(shù)組下標(biāo)
if (ret == -1)
{
printf("找不到要修改的人\n");
return;//讓函數(shù)直接返回
}
//修改
printf("請輸入要修改的姓名>:");
scanf("%s", pc->people[ret].name);
printf("請輸入要修改的年齡>:");
scanf("%d", &pc->people[ret].age);
printf("請輸入要修改的性別>:");
scanf("%s", pc->people[ret].sex);
printf("請輸入要修改的電話>:");
scanf("%s", pc->people[ret].phone);
printf("請輸入要修改的地址>:");
scanf("%s", pc->people[ret].address);
}test.c:
case modify: ModifyPeople(&contact); break;
接下來可以開始實習(xí)通訊錄的排序功能了,這里就按照年齡來進行一個排序,用到qsort這個函數(shù),其中cmp函數(shù)需要自己去寫
contact.h:
//排序 void SortByAge(Contact* pc);
contact.c:
int cmp(const void* e1, const void* e2)
{
Contact* p1 = (Contact*)e1;
Contact* p2 = (Contact*)e2;
if (p1->people[0].age > p2->people[1].age)
{
return 1;
}
else if (p1->people[0].age < p2->people[1].age)
{
return -1;
}
else
{
return 0;
}
}
void SortByAge(Contact* pc)
{
if (pc->num == 0)
{
printf("通訊錄已清空\n");
return;
}
int num = pc->num;
int width = sizeof(pc->people[0]);
qsort(pc->people, num, width, cmp);
}test.c:
case sort:
printf("按照年齡排序\n");
SortByAge(&contact);
PrintContact(&contact);
break;到這里通訊錄的功能就只剩下清空了,可以用到一開始的初始化函數(shù)InitialContact
test.c:
case empty:
printf("清空通訊錄\n");
InitialContact(&contact);
break;現(xiàn)在通訊錄的功能已經(jīng)全部實現(xiàn)了
可是這個通訊錄的功能還是有點不太好,就是通訊錄默認的大小就是存放1000個人的數(shù)據(jù),那么能不能創(chuàng)建一個可以隨著添加人數(shù)的增加而變大的通訊錄呢?鑒于最近學(xué)習(xí)了動態(tài)內(nèi)存管理,所以對通訊錄的功能做出了一點改進
對結(jié)構(gòu)體類型的修改:
contact.h
typedef struct Contact
{
People* people;
int num;
int capacity;//通訊錄的容量
} Contact;contact.c:
對InitialContact函數(shù)的修改:
void InitialContact(Contact* pc)
{
pc->people = (People*)calloc(3, sizeof(People));
if (pc->people == NULL)
{
perror("calloc");
return;
}
pc->num = 0;
pc->capacity = 3;
}對AddPeople函數(shù)的修改:
void AddPeople(Contact* pc)
{
if (pc->num == pc->capacity)
{
pc->people = realloc(pc->people, (pc->capacity + 2) * sizeof(People));
if (pc->people == NULL)
{
perror("realloc");
return;
}
pc->capacity += 2;
}
printf("請輸入姓名>:");
scanf("%s", pc->people[pc->num].name);
printf("請輸入年齡>:");
scanf("%d", &pc->people[pc->num].age);
printf("請輸入性別>:");
scanf("%s", pc->people[pc->num].sex);
printf("請輸入電話>:");
scanf("%s", pc->people[pc->num].phone);
printf("請輸入地址>:");
scanf("%s", pc->people[pc->num].address);
pc->num++;
}對排序函數(shù)中cmp函數(shù)的修改:
int cmp(const void* e1, const void* e2)
{
People* p1 = (People*)e1;
People* p2 = (People*)e2;
if (p1->age > p2->age)
{
return 1;
}
else if (p1->age < p2->age)
{
return -1;
}
else
{
return 0;
}
}test.c:
部分修改:
case empty:
printf("清空通訊錄\n");
FreeContact(&contact);
break;case Exit: FreeContact(&contact); break;
如下是完整的代碼:
contact.h:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
//類型的聲明
#define NameMax 20
#define SexMax 5
#define PhoneMax 20
#define AddressMax 30
enum input
{
Exit,
add,
sub,
search,
modify,
sort,
empty,
print
};
typedef struct People
{
char name[NameMax];
int age;
char sex[SexMax];
char phone[PhoneMax];
char address[AddressMax];
} People;
typedef struct Contact
{
People* people;
int num;
int capacity;//通訊錄的容量
} Contact;
//函數(shù)的聲明
//通訊錄初始化
void InitialContact(Contact* pc);
//添加通訊人
void AddPeople(Contact* pc);
//顯示通訊人信息
void PrintContact(const Contact* pc);
//刪除通訊人信息
void SubPeople(Contact* pc);
//查找通訊人
void SearchPeople(const Contact* pc);
//修改通訊人信息
void ModifyPeople(Contact* pc);
//排序
void SortByAge(Contact* pc);
//銷毀通訊錄
void FreeContact(Contact* pc);contact.c:
#include "contact.h"
void InitialContact(Contact* pc)
{
pc->people = (People*)calloc(3, sizeof(People));
if (pc->people == NULL)
{
perror("calloc");
return;
}
pc->num = 0;
pc->capacity = 3;
}
void AddPeople(Contact* pc)
{
if (pc->num == pc->capacity)
{
pc->people = realloc(pc->people, (pc->capacity + 2) * sizeof(People));
if (pc->people == NULL)
{
perror("realloc");
return;
}
pc->capacity += 2;
}
printf("請輸入姓名>:");
scanf("%s", pc->people[pc->num].name);
printf("請輸入年齡>:");
scanf("%d", &pc->people[pc->num].age);
printf("請輸入性別>:");
scanf("%s", pc->people[pc->num].sex);
printf("請輸入電話>:");
scanf("%s", pc->people[pc->num].phone);
printf("請輸入地址>:");
scanf("%s", pc->people[pc->num].address);
pc->num++;
}
void PrintContact(const Contact* pc)
{
printf("%-20s %-20s %-20s %-20s %-20s\n", "姓名", "年齡", "性別", "電話", "地址");
int i = 0;
for (i = 0; i < pc->num; i++)
{
printf("%-20s %-20d %-20s %-20s %-20s\n", pc->people[i].name, pc->people[i].age, pc->people[i].sex, pc->people[i].phone, pc->people[i].address);
}
}
int FindByName(Contact* pc, const char* name)
{
//遍歷每一個contact結(jié)構(gòu)體中people數(shù)組成員中的已存放數(shù)據(jù)的每一個結(jié)構(gòu)體
int i = 0;
for (i = 0; i < sizeof(pc->num); i++)
{
if (strcmp(pc->people[i].name, name) == 0)
{
return i;//找到了返回對應(yīng)結(jié)構(gòu)體的下標(biāo)
}
}
return -1;//找不到就返回-1
}
void SubPeople(Contact* pc)
{
if (pc->num == 0)//先判斷通訊錄中有無存儲信息
{
printf("通訊錄已清空\n");
return;
}
//1.找到
printf("請輸入要刪除的人的姓名;>");
char name[NameMax];
scanf("%s", name);
int ret = FindByName(pc, name);//用以接收放回的數(shù)組下標(biāo)
if (ret == -1)
{
printf("找不到要刪除的人\n");
return;//讓函數(shù)直接返回
}
//2.刪除
//從找到的那個下標(biāo)位置開始,后面的數(shù)組元素(通訊人結(jié)構(gòu)體)依次往前賦值
int j = 0;
for (j = ret; j < pc->num - 1; j++)
{
pc->people[j] = pc->people[j + 1];
}
printf("刪除成功\n");
pc->num--;//通訊人數(shù)量-1
}
void SearchPeople(const Contact* pc)
{
//查找
printf("請輸入要查找的人的姓名;>");
char name[NameMax];
scanf("%s", name);
int ret = FindByName(pc, name);//用以接收放回的數(shù)組下標(biāo)
if (ret == -1)
{
printf("找不到要查找的人\n");
return;//讓函數(shù)直接返回
}
//顯示
printf("%-20s %-20s %-20s %-20s %-20s\n", "姓名", "年齡", "性別", "電話", "地址");
printf("%-20s %-20d %-20s %-20s %-20s\n", pc->people[ret].name, pc->people[ret].age, pc->people[ret].sex, pc->people[ret].phone, pc->people[ret].address);
}
void ModifyPeople(Contact* pc)
{
//查找
printf("請輸入要修改的人的姓名;>");
char name[NameMax];
scanf("%s", name);
int ret = FindByName(pc, name);//用以接收放回的數(shù)組下標(biāo)
if (ret == -1)
{
printf("找不到要修改的人\n");
return;//讓函數(shù)直接返回
}
//修改
printf("請輸入要修改的姓名>:");
scanf("%s", pc->people[ret].name);
printf("請輸入要修改的年齡>:");
scanf("%d", &pc->people[ret].age);
printf("請輸入要修改的性別>:");
scanf("%s", pc->people[ret].sex);
printf("請輸入要修改的電話>:");
scanf("%s", pc->people[ret].phone);
printf("請輸入要修改的地址>:");
scanf("%s", pc->people[ret].address);
}
int cmp(const void* e1, const void* e2)
{
People* p1 = (People*)e1;
People* p2 = (People*)e2;
if (p1->age > p2->age)
{
return 1;
}
else if (p1->age < p2->age)
{
return -1;
}
else
{
return 0;
}
}
void SortByAge(Contact* pc)
{
if (pc->num == 0)
{
printf("通訊錄已清空\n");
return;
}
int num = pc->num;
int width = sizeof(People);
qsort(pc->people, num, width, cmp);
}
void FreeContact(Contact* pc)
{
free(pc->people);
pc->people = NULL;
pc->num = 0;
pc->capacity = 0;
}test.c:
#include "contact.h"
void menu()
{
printf("***********************************\n");
printf("****** 1.add 2.del ******\n");
printf("****** 3.search 4.modify ******\n");
printf("****** 5.sort 6.empty ******\n");
printf("****** 7.print 0.exit ******\n");
printf("***********************************\n");
}
int main()
{
//通訊錄:1.add 2.del 3.search 4,modify 5.sort 6.empty 7.print 0.exit
//創(chuàng)建通訊錄
Contact contact;
//初始化通訊錄
InitialContact(&contact);
int input = 0;
do
{
menu();
printf("請選擇功能>:");
scanf("%d", &input);
switch (input)
{
case add:
printf("添加通訊人\n");
AddPeople(&contact);
break;
case sub:
SubPeople(&contact);
break;
case search:
SearchPeople(&contact);
break;
case modify:
ModifyPeople(&contact);
break;
case sort:
printf("按照年齡排序\n");
SortByAge(&contact);
PrintContact(&contact);
break;
case empty:
printf("清空通訊錄\n");
FreeContact(&contact);
break;
case print:
printf("顯示通訊人信息\n");
PrintContact(&contact);
break;
case Exit:
FreeContact(&contact);
break;
default:
printf("請重新輸入\n");
break;
}
} while (input);
return 0;
}到此這篇關(guān)于C語言實現(xiàn)通訊錄功能的流程與代碼的文章就介紹到這了,更多相關(guān)C語言通訊錄內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
基于C語言char與unsigned char的區(qū)別介紹
本篇文章小編為大家介紹,基于C語言char與unsigned char的區(qū)別介紹。需要的朋友參考下2013-04-04
C++應(yīng)用Eigen庫對應(yīng)實現(xiàn)matlab中部分函數(shù)問題
這篇文章主要介紹了C++應(yīng)用Eigen庫對應(yīng)實現(xiàn)matlab中部分函數(shù)問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-12-12

