该通讯录可以用来存储1000个人的信息,每个人的信息包括:姓名、性别、年龄、电话、住址
提供方法:
添加联系人信息
删除指定联系人信息
查找指定联系人信息
修改指定联系人信息
显示所有联系人信息
清空所有联系人
以名字排序所有联系人
在这里实现通讯录用三个模块
test.c--------------------测试通讯录的功能
contact.h---------------通讯录的实现(头文件和函数的声明)
contact.c---------------通讯录的实现(各个功能的实现)
首先建立一个菜单,菜单立马应该包括通讯录立马该有的功能,以便于用户的操作。
void menu()
{
printf("*************************************\n");
printf("****** 1. add 2. del ******\n");
printf("****** 3. search 4. modify ******\n");
printf("****** 5. show 6. sort_name ******\n");
printf("****** 7.clcall 0. exit ******\n");
printf("*************************************\n");
}
主函数包含了创建通讯录,初始化,还使用了do while函数和switch函数,通过input读取用户输入的数字,利用switch函数进行调用各个函数的功能。
int main()
{
int input = 0;
//初始化通讯录
Contact con;
Init_contact(&con);
do {
menu();
printf("请选择:");
scanf("%d", &input);
switch (input)
{
case 1:
Addcontact(&con);
break;
case 2:
delcontact(&con);
break;
case 3:
search(&con);
break;
case 4:
modify(&con);
break;
case 5:
showcontact(&con);
break;
case 6:
sort_name(&con);
break;
case 7:
clcall(&con);
break;
case 0:
printf("退出通讯录\n");
break;
default:
printf("输入错误,请重新输入");
break;
}
} while (input);
return 0;
}
主函数首先使用Contact结构体创建了一个通讯录,然后再使用Init_contact(&con);进行了通讯录的初始化。该部分结构体和函数代码如下。
结构体:为了方便后期的处理数组大小,所以我们可以利用define来定义数组的大小。
#define date_MAX 1000
#define name_MAX 20
#define sex_MAX 4
#define tele_MAX 12
#define addr_MAX 10
typedef struct PeoInfo
{
char name[name_MAX];
int age;
char sex[sex_MAX];
char tele[tele_MAX];
char addr[addr_MAX];
} PeoInfo;
//创建通讯录结构体(静态版本)
//typedef struct Contact
//{
// PeoInfo date[date_MAX];//存放联系人数组
// int sz = 0;//存放联系人的个数
//}Contact;
//创建通讯录结构体(动态版本)
typedef struct Contact
{
PeoInfo *date;//存放联系人数组
int sz = 0;//存放联系人的个数
int capacity = 0;//当前联系人的最大容量
}Contact;
使用了memset将通讯录初始化为0。
//初始化联系人(静态版本)
//void Init_contact(Contact* pc)
//{
// assert(pc);
// pc -> sz = { 0 };
// memset(pc->date, 0, sizeof(pc->date));
//}
//动态版本
void Init_contact(Contact* pc)
{
assert(pc);
pc->sz = 0 ;
PeoInfo * ptr =( PeoInfo*)calloc(DEFAULT_SZ, sizeof(PeoInfo));
if (ptr == NULL)
{
perror("Init_contact::calloc");
return ;
}
else
{
pc->date = ptr;
pc->capacity = DEFAULT_SZ;
}
}
//增加联系人(静态版本)
//void Addcontact(Contact* pc)
//{
// assert(pc);
// if (pc->sz == date_MAX)
// {
// printf("通讯录已满\n");
// return;
// }
// printf("请输入姓名:");
// scanf("%s", pc->date[pc->sz].name);
// printf("请输入年龄:");
// scanf("%d", &(pc->date[pc->sz].age));
// printf("请输入性别:");
// scanf("%s", pc->date[pc->sz].sex);
// printf("请输入电话:");
// scanf("%s", pc->date[pc->sz].tele);
// printf("请输入地址:");
// scanf("%s", pc->date[pc->sz].addr);
//
// pc->sz++;
//}
//动态版本
void check_capacity(Contact* pc)
{
if (pc->sz == pc->capacity)
{
PeoInfo* ptr =(PeoInfo*)realloc(pc->date, (pc->capacity+INC_SZ)*sizeof(PeoInfo));
if (ptr == NULL)
{
perror("check_capacity::realloc");
return;
}
pc->date = ptr;
pc->capacity += INC_SZ;
printf("增容成功\n");
}
}
void Addcontact(Contact* pc)
{
assert(pc);
check_capacity(pc);
printf("请输入姓名:");
scanf("%s", pc->date[pc->sz].name);
printf("请输入年龄:");
scanf("%d", &(pc->date[pc->sz].age));
printf("请输入性别:");
scanf("%s", pc->date[pc->sz].sex);
printf("请输入电话:");
scanf("%s", pc->date[pc->sz].tele);
printf("请输入地址:");
scanf("%s", pc->date[pc->sz].addr);
pc->sz++;
}
当用户按下1,进入Addcontact函数,首先判断通讯录是否已满足最大容量,若没有满,对通讯录进行赋值,用户只需要根据提示的信息进行输入数据就可以了。添加完成后,就让sz++;记录当前通讯录实际有效人数。
静态版本:
动态版本:
void showcontact(const Contact* pc)
{
assert(pc);
if (pc->sz == 0)
{
printf("联系人为空\n");
return;
}
else
{
printf("%-20s\t%-4s\t%-4s\t%-12s\t%-10s\n","姓名","年龄","性别","电话","地址");
}
int i = 0;
for ( i = 0; i < pc->sz; i++)
{
printf("%-20s\t%d\t%-4s\t%-12s\t%-10s\n", pc->date[i].name,
(pc->date[i].age),
pc->date[i].sex,
pc->date[i].tele,
pc->date[i].addr);
}
}
首先判断联系人是否为空再进行是否打印,打印时,先打印出对应的联系人数据名称;便于用户阅读。
利用for循环遍历打印联系人信息。
打印时,为了使得打印出来的数据整齐,再数据中加入了前面的数字,还有\t,数字代表域宽:比如-20就代表域宽是20(长度不够20用空格填充),负号代表左对齐,默认是右对齐的。\t表示tab键,相当于一个分隔符。
删除联系人首先需要进行查找,这里定义了一个查找函数,查看联系人是否存在。
int Findname(const Contact* pc, char* name)
{
assert(pc);
int i = 0;
for (i = 0; i < pc->sz; i++)
{
if (strcmp(pc->date[i].name,name)==0)
{
return i;
}
}
return -1;
}
函数联系人函数,首先判断联系人是否为空,然后根据用户输入的联系人,利用Findname函数查看要删除的联系人是否存在,如果存在,进行删除,然后将sz减1,确定有效联系人的个数。
void delcontact(Contact* pc)
{
assert(pc);
char name[name_MAX];
if (pc->sz == 0)
{
printf("联系人为空,无法删除\n");
return;
}
printf("请输入要删除的联系人:");
scanf("%s", name);
//查找
int pos = Findname(pc, name);
if (pos == -1)
{
printf("该通讯录没有存在这个名字\n");
return;
}
//删除
int i = 0;
for (i = pos; i < pc->sz; i++)
{
pc->date[i] = pc->date[i + 1];
}
pc->sz--;
printf("删除成功\n");
}
void search(const Contact* pc)
{
assert(pc);
printf("%-20s\t%-4s\t%-4s\t%-12s\t%-10s\n", "姓名", "年龄", "性别", "电话", "地址");
char name[name_MAX];
printf("请输入你要查找的联系人:");
scanf("%s", name);
int pos = Findname(pc, name);
if (pos == -1)
{
printf("查无此人\n");
return;
}
else
{
printf("%-20s\t%d\t%-4s\t%-12s\t%-10s\n", pc->date[pos].name,
(pc->date[pos].age),
pc->date[pos].sex,
pc->date[pos].tele,
pc->date[pos].addr);
}
}
根据用户输入的联系人姓名,利用Findname查找该联系人是否存在,如果存在,打印出该联系人的信息。
void modify(Contact* pc)
{
assert(pc);
char name[name_MAX];
printf("请输入你要修改的名字:");
scanf("%s", name);
int pos = Findname(pc, name);
if (pos == -1)
{
printf("查无此人\n");
return;
}
printf("请输入姓名:");
scanf("%s", pc->date[pos].name);
printf("请输入年龄:");
scanf("%d", &(pc->date[pos].age));
printf("请输入性别:");
scanf("%s", pc->date[pos].sex);
printf("请输入电话:");
scanf("%s", pc->date[pos].tele);
printf("请输入地址:");
scanf("%s", pc->date[pos].addr);
printf("修改完成\n");
}
根据用户输入的联系人姓名,利用Findname查找该联系人是否存在,如果存在,用户根据提示信息,将联系人的信息进行修改
void sort_name(Contact* pc)
{
assert(pc);
if (pc->sz == 0)
{
printf("联系人为空,无需排序\n");
return;
}
int i = 0;
int j = 0;
for (i = 0; i < pc->sz - 1; i++)
{
for (j = 0; j < pc->sz - i-1; j++)
{
if (strcmp( pc->date[j].name, pc->date[j + 1].name) > 0)
{
PeoInfo tmp;
tmp = pc->date[j];
pc->date[j] = pc->date[j + 1];
pc->date[j + 1] = tmp;
}
}
}
printf("排序成功\n");
}
排序功能主要使用了冒泡排序,利用strcmp判断联系人的名字首字母大小,根据字母表的顺序,将联系人的信息进行排序。
void clcall(Contact* pc)
{
assert(pc);
printf("你确定要清空所有联系人吗?(yes/no)\n");
char str[5] = {0};
scanf("%s", &str);
if (strcmp(str, "yes") == 0)
{
pc->sz = 0;
printf("清空所有联系人成功\n");
}
else if (strcmp(str, "yes") != 0)
{
printf("已取消清空联系人");
}
else
{
printf("输入错误,请重新输入");
}
}
清空所有联系人,使用if语句进行确认用户是否确定清空,若用户输入yes,将sz置为0,清空所有联系人的数据。
当用户按下0退出通讯录,为了避免之前输入的联系人的数据丢失,所以先将之前的联系人信息保存起来。
void SaveContact(Contact* pc)
{
//写数据
//1、打开文件
FILE* pf = fopen("contact.txt", "wb");
if (NULL == pf)
{
perror("SaveContact");
}
else
{
//写数据
int i = 0;
for ( i = 0; i < pc->sz; i++)
{
fwrite(pc->date + i, sizeof(PeoInfo), 1, pf);
}
fclose(pf);
pf = NULL;
printf("保存成功\n");
}
}
当用户按下0,销毁通讯录,使用free函数释放动态开辟的数组指针,同时对sz和capacity置0以及对通讯录指针置为空指针。
//销毁通讯录
void Destory_contact(Contact* pc)
{
free(pc->date);
pc->date = NULL;
pc->capacity = 0;
pc->sz = 0;
pc = NULL;
}
该函数放在初始化函数,将之前保存的通讯录进行初始化。
//加载文件信息到通讯录
void LoadContact(Contact* pc)
{
//读数据
//1.打开文件
FILE* pf = fopen("contact.txt", "rb");
if (NULL == pf)
{
perror("LoadContact");
}
else
{
; //2.读数据
PeoInfo tmp = { 0 };
int i = 0;
while ( fread(&tmp,sizeof(PeoInfo),1,pf) )
{
//增容
check_capacity(pc);
pc->date[i] = tmp;
pc->sz++;
i++;
}
fclose(pf);
pf = NULL;
}
}
#include
#include
#include
#include
#define date_MAX 1000
#define DEFAULT_SZ 3
#define INC_SZ 2
#define name_MAX 20
#define sex_MAX 4
#define tele_MAX 12
#define addr_MAX 10
//创建联系人结构体
typedef struct PeoInfo
{
char name[name_MAX];
int age;
char sex[sex_MAX];
char tele[tele_MAX];
char addr[addr_MAX];
} PeoInfo;
//创建通讯录结构体(静态版本)
//typedef struct Contact
//{
// PeoInfo date[date_MAX];//存放联系人数组
// int sz = 0;//存放联系人的个数
//}Contact;
typedef struct Contact
{
PeoInfo *date;//存放联系人数组
int sz = 0;//存放联系人的个数
int capacity = 0;//当前联系人的最大容量
}Contact;
//初始化
void Init_contact(Contact* pc);
//增加联系人
void Addcontact(Contact* pc);
//显示联系人信息
void showcontact(const Contact* pc);
//删除联系人
void delcontact(Contact* pc);
//查找联系人
void search(const Contact* pc);
//修改联系人
void modify(Contact* pc);
//以名字进行排序
void sort_name(Contact* pc);
//清空所有联系人
void clcall(Contact* pc);
//初始化联系人(静态版本)
//void Init_contact(Contact* pc)
//{
// assert(pc);
// pc -> sz = { 0 };
// memset(pc->date, 0, sizeof(pc->date));
//}
void Init_contact(Contact* pc)
{
assert(pc);
pc->sz = 0 ;
PeoInfo * ptr =( PeoInfo*)calloc(DEFAULT_SZ, sizeof(PeoInfo));
if (ptr == NULL)
{
perror("Init_contact::calloc");
return ;
}
else
{
pc->date = ptr;
pc->capacity = DEFAULT_SZ;
}
}
//销毁通讯录
void Destory_contact(Contact* pc)
{
free(pc->date);
pc->date = NULL;
pc->capacity = 0;
pc->sz = 0;
pc = NULL;
}
//增加联系人(静态版本)
//void Addcontact(Contact* pc)
//{
// assert(pc);
// if (pc->sz == date_MAX)
// {
// printf("通讯录已满\n");
// return;
// }
// printf("请输入姓名:");
// scanf("%s", pc->date[pc->sz].name);
// printf("请输入年龄:");
// scanf("%d", &(pc->date[pc->sz].age));
// printf("请输入性别:");
// scanf("%s", pc->date[pc->sz].sex);
// printf("请输入电话:");
// scanf("%s", pc->date[pc->sz].tele);
// printf("请输入地址:");
// scanf("%s", pc->date[pc->sz].addr);
//
// pc->sz++;
//}
void check_capacity(Contact* pc)
{
if (pc->sz == pc->capacity)
{
PeoInfo* ptr =(PeoInfo*)realloc(pc->date, (pc->capacity+INC_SZ)*sizeof(PeoInfo));
if (ptr == NULL)
{
perror("check_capacity::realloc");
return;
}
pc->date = ptr;
pc->capacity += INC_SZ;
printf("增容成功\n");
}
}
//动态版本
void Addcontact(Contact* pc)
{
assert(pc);
check_capacity(pc);
printf("请输入姓名:");
scanf("%s", pc->date[pc->sz].name);
printf("请输入年龄:");
scanf("%d", &(pc->date[pc->sz].age));
printf("请输入性别:");
scanf("%s", pc->date[pc->sz].sex);
printf("请输入电话:");
scanf("%s", pc->date[pc->sz].tele);
printf("请输入地址:");
scanf("%s", pc->date[pc->sz].addr);
pc->sz++;
}
//显示联系人信息
void showcontact(const Contact* pc)
{
assert(pc);
if (pc->sz == 0)
{
printf("联系人为空\n");
return;
}
else
{
printf("%-20s\t%-4s\t%-4s\t%-12s\t%-10s\n","姓名","年龄","性别","电话","地址");
}
int i = 0;
for ( i = 0; i < pc->sz; i++)
{
printf("%-20s\t%d\t%-4s\t%-12s\t%-10s\n", pc->date[i].name,
(pc->date[i].age),
pc->date[i].sex,
pc->date[i].tele,
pc->date[i].addr);
}
printf("添加联系人成功\n");
}
int Findname(const Contact* pc, char* name)
{
assert(pc);
int i = 0;
for (i = 0; i < pc->sz; i++)
{
if (strcmp(pc->date[i].name,name)==0)
{
return i;
}
}
return -1;
}
//删除联系人
void delcontact(Contact* pc)
{
assert(pc);
char name[name_MAX];
if (pc->sz == 0)
{
printf("联系人为空,无法删除\n");
return;
}
printf("请输入要删除的联系人:");
scanf("%s", name);
//查找
int pos = Findname(pc, name);
if (pos == -1)
{
printf("该通讯录没有存在这个名字\n");
return;
}
//删除
int i = 0;
for (i = pos; i < pc->sz; i++)
{
pc->date[i] = pc->date[i + 1];
}
pc->sz--;
printf("删除成功\n");
}
//查找联系人
void search(const Contact* pc)
{
assert(pc);
printf("%-20s\t%-4s\t%-4s\t%-12s\t%-10s\n", "姓名", "年龄", "性别", "电话", "地址");
char name[name_MAX];
printf("请输入你要查找的联系人:");
scanf("%s", name);
int pos = Findname(pc, name);
if (pos == -1)
{
printf("查无此人\n");
return;
}
else
{
printf("%-20s\t%d\t%-4s\t%-12s\t%-10s\n", pc->date[pos].name,
(pc->date[pos].age),
pc->date[pos].sex,
pc->date[pos].tele,
pc->date[pos].addr);
}
}
//修改联系人
void modify(Contact* pc)
{
assert(pc);
char name[name_MAX];
printf("请输入你要修改的名字:");
scanf("%s", name);
int pos = Findname(pc, name);
if (pos == -1)
{
printf("查无此人\n");
return;
}
printf("请输入姓名:");
scanf("%s", pc->date[pos].name);
printf("请输入年龄:");
scanf("%d", &(pc->date[pos].age));
printf("请输入性别:");
scanf("%s", pc->date[pos].sex);
printf("请输入电话:");
scanf("%s", pc->date[pos].tele);
printf("请输入地址:");
scanf("%s", pc->date[pos].addr);
printf("修改完成\n");
}
//以名字进行排序
void sort_name(Contact* pc)
{
assert(pc);
if (pc->sz == 0)
{
printf("联系人为空,无需排序\n");
return;
}
int i = 0;
int j = 0;
for (i = 0; i < pc->sz - 1; i++)
{
for (j = 0; j < pc->sz - i-1; j++)
{
if (strcmp( pc->date[j].name, pc->date[j + 1].name) > 0)
{
PeoInfo tmp;
tmp = pc->date[j];
pc->date[j] = pc->date[j + 1];
pc->date[j + 1] = tmp;
}
}
}
printf("排序成功\n");
}
//清空所有联系人
void clcall(Contact* pc)
{
assert(pc);
printf("你确定要清空所有联系人吗?(yes/no)\n");
char str[5] = {0};
scanf("%s", &str);
if (strcmp(str, "yes") == 0)
{
pc->sz = 0;
printf("清空所有联系人成功\n");
}
else if (strcmp(str, "yes") != 0)
{
printf("已取消清空联系人");
}
else
{
printf("输入错误,请重新输入");
}
}
void menu()
{
printf("*************************************\n");
printf("****** 1. add 2. del ******\n");
printf("****** 3. search 4. modify ******\n");
printf("****** 5. show 6. sort_name ******\n");
printf("****** 7.clcall 0. exit ******\n");
printf("*************************************\n");
}
int main()
{
int input = 0;
Contact con;
Init_contact(&con);
do {
menu();
printf("请选择:");
scanf("%d", &input);
switch (input)
{
case 1:
Addcontact(&con);
break;
case 2:
delcontact(&con);
break;
case 3:
search(&con);
break;
case 4:
modify(&con);
break;
case 5:
showcontact(&con);
break;
case 6:
sort_name(&con);
break;
case 7:
clcall(&con);
break;
case 0:
printf("退出通讯录\n");
break;
default:
printf("输入错误,请重新输入");
break;
}
} while (input);
return 0;
}