通讯录的功能:
通讯录可以用来存储1000个人的信息,每个人的信息包括:姓名、性别、年龄、电话、住址。
test .c
void menu()
{
printf("**************************************\n");
printf("****** 1.add 2.sub *********\n");
printf("****** 3.search 4.modify ******\n");
printf("****** 5.sort 6.print ******\n");
printf("************ 0.exit ***********\n");
printf("**************************************\n");
}
在这儿我们需要创建两个结构体,一个用来存放人的信息:姓名、性别、年龄、电话、住址;另一个用来存放通讯录的信息。
contact.h
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 data[MAX];//存储联系人的信息
int count;//存储联系人的数量
}Contact;
我们需要根据用户的需求进行选择,比如用户输入1,我们就知道他是要添加联系人,输入0,就是退出通讯录,在这儿我们可以用到枚举,将选择一一列举出来:
contact.h
enum Point
{
EXIT,
ADD,
DEL,
SEARCH,
MODIFY,
SORT,
PRINT
};
test .c
int main()
{
int input = 0;
do
{
menu();
printf("请选择:");
scanf("%d", &input);
switch (input)
{
case ADD:
break;
case DEL:
break;
case SEARCH:
break;
case MODIFY:
break;
case SORT:
break;
case PRINT:
break;
case EXIT:
printf("退出通讯录\n");
break;
default:
printf("输入错误,请重新输入\n");
break;
}
} while (input);
return 0;
}
为了能更好的对我们的通讯录进行,我们将一些代码中需要多次出现的数使用#define进行定义:
#define MAX 1000
#define NAME_MAX 20
#define SEX_MAX 5
#define TELE_MAX 12
#define ADDR_MAX 20
首先我们得先创建一个通讯录,然后对通讯录进行初始化:
test .c
Contact con;//创建一个通讯录
Init_Contact(&con);//初始化通讯录
contact .c
void Init_Contact(Contact* pc)
{
pc->count = 0;//通讯录初始数量为0
memset(pc->data, 0, sizeof(pc->data));//将存储联系人数组中每个人的信息初始化为0
}
contact .h
void Init_Contact(Contact* pc);
我们添加联系人信息的时候首先要得判断通讯是否满了,如果通讯满了,我们就添加不了,如果没满,我们就开始添加。
contact .c
void Add_Contact(Contact* pc)
{
assert(pc);
if (pc->count == MAX)
{
printf("通讯录已满,无法添加\n");
}
else
{
printf("开始添加\n");
printf("请输入添加人的姓名:");
scanf("%s", pc->data[pc->count].name);
printf("请输入添加人的年龄:");
scanf("%d", &(pc->data[pc->count].age));
printf("请输入添加人的性别:");
scanf("%s", pc->data[pc->count].sex);
printf("请输入添加人的电话:");
scanf("%s", pc->data[pc->count].tele);
printf("请输入添加人的地址:");
scanf("%s", pc->data[pc->count].addr);
pc->count++;
printf("添加成功\n");
}
}
contact .h
void Add_Contact(Contact* pc);
我们添加完联系人的信息以后,得看看我们添加的信息对不对,所以得把联系人打印出来看一看:
contact .c
void Print_Contact(Contact* pc)
{
assert(pc);
int i = 0;
printf("%20s %5s %5s %12s %12s\n","姓名", "年龄", "性别", "电话", "地址");
for (i = 0; i < pc->count; i++)
{
printf("%20s %5d %5s %12s %12s\n",pc->data[i].name, pc->data[i].age, pc->data[i].sex,
pc->data[i].tele, pc->data[i].addr);
}
}
contact .h
void Print_Contact(Contact* pc);
删除联系人的前提是我们的先找到这个联系人,然后再删除,而删除联系人实际上就是把要删除的这个联系人的信息全给覆盖掉。也就是让他后面的每个联系人往前移动一位就行了。我们这儿就以查找姓名为例吧:
contact .c
static int find_by_name(Contact* pc, char name[])
{
assert(pc);
int i = 0;
for (i = 0; i < pc->count; i++)
{
if (strcmp(name, pc->data[i].name) == 0)
{
return i;
}
}
return 0;
}
void Del_Contact(Contact* pc)
{
assert(pc);
int i = 0;
//查找联系人
char name[MAX];
printf("请输入要删除的联系人的名字:");
scanf("%s", name);
int pos = find_by_name(pc,name);
if (pos)
{
for (i = pos; i < pc->count - 1; i++)
{
pc->data[i] = pc->data[i + 1];
}
pc->count--;
printf("删除成功\n");
}
else
{
printf("要删除的人不存在\n");
}
}
contact .h
void Del_Contact(Contact* pc);
在这儿要注意的是,我们删除一个联系人的信息以后,count是要进行减减的。
查找联系人就是输入联系人的某个信息,然后找到了在打印出来,我们依然以查找姓名为例:
contact .c
void Search_Contact(Contact* pc)
{
assert(pc);
int i = 0;
char name[MAX];
printf("请输入要查找的联系人的名字:");
scanf("%s", name);
int pos = find_by_name(pc, name);
if (pos)
{
printf("%20s %5s %5s %12s %12s\n", "姓名", "年龄", "性别", "电话", "地址");
printf("%20s %5d %5s %12s %12s\n", pc->data[pos].name, pc->data[pos].age, pc->data[pos].sex,
pc->data[pos].tele, pc->data[pos].addr);
}
else
{
printf("要查找的人不存在\n");
}
}
contact .h
void Search_Contact(Contact* pc);
修改联系人其实也一样,就是输先把这个联系人找到,找到了之后逐项进行修改,我们依然以查找姓名为例:
contact .c
void Modify_Contact(Contact* pc)
{
assert(pc);
int i = 0;
char name[MAX];
printf("请输入要修改的联系人的名字:");
scanf("%s", name);
int pos = find_by_name(pc, name);
if (pos)
{
printf("开始修改\n");
printf("请输入修改人的姓名:");
scanf("%s", pc->data[pos].name);
printf("请输入修改人的年龄:");
scanf("%d", &(pc->data[pos].age));
printf("请输入修改人的性别:");
scanf("%s", pc->data[pos].sex);
printf("请输入修改人的电话:");
scanf("%s", pc->data[pos].tele);
printf("请输入修改人的地址:");
scanf("%s", pc->data[pos].addr);
printf("修改成功\n");
}
else
{
printf("要修改的人不存在\n");
}
}
contact .h
void Modify_Contact(Contact* pc);
在这儿我们可以使用我们的qsort函数,当然,我们也可以自己将冒泡排序函数改造一番:
contact .c
//排序所以联系人
static int cmp_by_name(const void* e1, const void* e2)
{
return strcmp(((PeoInfo*)e1)->name, ((PeoInfo*)e2)->name);
}
static void swap(char* buf1, char* buf2, size_t width)
{
unsigned int i = 0;
for (i = 0; i < width; i++)
{
char tmp = *buf1;
*buf1 = *buf2;
*buf2 = tmp;
buf1++;
buf2++;
}
}
static void my_bubble_sort(void* base, size_t num, size_t width, int(*cmp)(const void* e1, const void* e2))
{
unsigned int i = 0;
unsigned int j = 0;
for (i = 0; i < num-1; i++)
{
for (j = 0; j < num - 1 - i; j++)
{
if (cmp_by_name((char*)base + j * width, (char*)base + (j + 1) * width )> 0)
{
swap(((char*)base + j * width), ((char*)base + (j + 1) * width), width);
}
}
}
}
void Sort_Contact(Contact* pc)
{
my_bubble_sort(pc->data, pc->count, sizeof(PeoInfo), cmp_by_name);
printf("排序成功\n");
}
contact .h
void Sort_Contact(Contact* pc);
整体代码:
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.print ******\n");
printf("************ 0.exit ***********\n");
printf("**************************************\n");
}
int main()
{
Contact con;//创建一个通讯录
Init_Contact(&con);//初始化通讯录
int input = 0;
do
{
menu();
printf("请选择:");
scanf("%d", &input);
switch (input)
{
case ADD:
//添加联系人
Add_Contact(&con);
break;
case DEL:
//删除联系人
Del_Contact(&con);
break;
case SEARCH:
//查找联系人
Search_Contact(&con);
break;
case MODIFY:
//修改联系人
Modify_Contact(&con);
break;
case SORT:
//排序所有联系人
Sort_Contact(&con);
break;
case PRINT:
//打印联系人
Print_Contact(&con);
break;
case EXIT:
printf("退出通讯录\n");
break;
default:
printf("输入错误,请重新输入\n");
break;
}
} while (input);
return 0;
}
contact .c
#include"contact.h"
//初始化通讯录
void Init_Contact(Contact* pc)
{
assert(pc);
pc->count = 0;
memset(pc->data, 0, sizeof(pc->data));
}
//添加联系人
void Add_Contact(Contact* pc)
{
assert(pc);
if (pc->count == MAX)
{
printf("通讯录已满,无法添加\n");
}
else
{
printf("开始添加\n");
printf("请输入添加人的姓名:");
scanf("%s", pc->data[pc->count].name);
printf("请输入添加人的年龄:");
scanf("%d", &(pc->data[pc->count].age));
printf("请输入添加人的性别:");
scanf("%s", pc->data[pc->count].sex);
printf("请输入添加人的电话:");
scanf("%s", pc->data[pc->count].tele);
printf("请输入添加人的地址:");
scanf("%s", pc->data[pc->count].addr);
pc->count++;
printf("添加成功\n");
}
}
//打印联系人
void Print_Contact(Contact* pc)
{
assert(pc);
int i = 0;
printf("%20s %5s %5s %12s %12s\n","姓名", "年龄", "性别", "电话", "地址");
for (i = 0; i < pc->count; i++)
{
printf("%20s %5d %5s %12s %12s\n",pc->data[i].name, pc->data[i].age, pc->data[i].sex,
pc->data[i].tele, pc->data[i].addr);
}
}
//删除联系人
static int find_by_name(Contact* pc, char name[])
{
assert(pc);
int i = 0;
for (i = 0; i < pc->count; i++)
{
if (strcmp(name, pc->data[i].name) == 0)
{
return i;
}
}
return 0;
}
void Del_Contact(Contact* pc)
{
assert(pc);
int i = 0;
//查找联系人
char name[MAX];
printf("请输入要删除的联系人的名字:");
scanf("%s", name);
int pos = find_by_name(pc,name);
if (pos)
{
for (i = pos; i < pc->count - 1; i++)
{
pc->data[i] = pc->data[i + 1];
}
pc->count--;
printf("删除成功\n");
}
else
{
printf("要删除的人不存在\n");
}
}
//查找联系人
void Search_Contact(Contact* pc)
{
assert(pc);
int i = 0;
//查找联系人
char name[MAX];
printf("请输入要查找的联系人的名字:");
scanf("%s", name);
int pos = find_by_name(pc, name);
if (pos)
{
printf("%20s %5s %5s %12s %12s\n", "姓名", "年龄", "性别", "电话", "地址");
printf("%20s %5d %5s %12s %12s\n", pc->data[pos].name, pc->data[pos].age, pc->data[pos].sex,
pc->data[pos].tele, pc->data[pos].addr);
}
else
{
printf("要查找的人不存在\n");
}
}
//修改联系人
void Modify_Contact(Contact* pc)
{
assert(pc);
int i = 0;
//查找联系人
char name[MAX];
printf("请输入要修改的联系人的名字:");
scanf("%s", name);
int pos = find_by_name(pc, name);
if (pos)
{
printf("开始修改\n");
printf("请输入修改人的姓名:");
scanf("%s", pc->data[pos].name);
printf("请输入修改人的年龄:");
scanf("%d", &(pc->data[pos].age));
printf("请输入修改人的性别:");
scanf("%s", pc->data[pos].sex);
printf("请输入修改人的电话:");
scanf("%s", pc->data[pos].tele);
printf("请输入修改人的地址:");
scanf("%s", pc->data[pos].addr);
printf("修改成功\n");
}
else
{
printf("要修改的人不存在\n");
}
}
//排序所以联系人
static int cmp_by_name(const void* e1, const void* e2)
{
return strcmp(((PeoInfo*)e1)->name, ((PeoInfo*)e2)->name);
}
static void swap(char* buf1, char* buf2, size_t width)
{
unsigned int i = 0;
for (i = 0; i < width; i++)
{
char tmp = *buf1;
*buf1 = *buf2;
*buf2 = tmp;
buf1++;
buf2++;
}
}
static void my_bubble_sort(void* base, size_t num, size_t width, int(*cmp)(const void* e1, const void* e2))
{
unsigned int i = 0;
unsigned int j = 0;
for (i = 0; i < num-1; i++)
{
for (j = 0; j < num - 1 - i; j++)
{
if (cmp_by_name((char*)base + j * width, (char*)base + (j + 1) * width )> 0)
{
swap(((char*)base + j * width), ((char*)base + (j + 1) * width), width);
}
}
}
}
void Sort_Contact(Contact* pc)
{
my_bubble_sort(pc->data, pc->count, sizeof(PeoInfo), cmp_by_name);
printf("排序成功\n");
}
contact .h
#include
#include
#include
#define MAX 1000
#define NAME_MAX 20
#define SEX_MAX 5
#define TELE_MAX 12
#define ADDR_MAX 20
enum Point
{
EXIT,
ADD,
DEL,
SEARCH,
MODIFY,
SORT,
PRINT
};
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 data[MAX];//存储联系人的信息
int count;//存储联系人的数量
}Contact;
//初始化通讯录
void Init_Contact(Contact* pc);
//添加联系人
void Add_Contact(Contact* pc);
//打印联系人
void Print_Contact(Contact* pc);
//删除联系人
void Del_Contact(Contact* pc);
//查找联系人
void Search_Contact(Contact* pc);
//修改联系人
void Modify_Contact(Contact* pc);
//排序所以联系人
void Sort_Contact(Contact* pc);
到这儿我们静态版本的通讯录就实现了。接下来就是动态版本的:
在静态版本通讯录中,我们通讯录的空间开辟了以后就不能更改,如果觉得他大了或者是小了,需要去更改全局变量的才可以,而在程序运行过程中无法更改,接下来我们就实现一个动态版本的,可以自己进行扩容,减少空间的浪费:
//静态版本
//typedef struct Contact
//{
// PeoInfo data[MAX];//存储联系人的信息
// int count;//存储联系人的数量
//}Contact;
//动态版本
typedef struct Contact
{
PeoInfo* data;//存储联系人的信息
int count;//存储联系人的数量
int capacity;//通讯录的初始容量
}Contact;
在这儿,我们将数组改成了结构体指针的形式,并且增加一个capacity变量表示通讯录的容量,有了这两个条件,我们就了使用动态内存开辟函数进行空间的开辟。
我们假设通讯录初始容量为“3”吧,然后将空间开辟出来:
#define INT_SZ 3
//静态版本
//初始化通讯录
//void Init_Contact(Contact* pc)
//{
// assert(pc);
// pc->count = 0;
// memset(pc->data, 0, sizeof(pc->data));
//}
//动态版本
void Init_Contact(Contact* pc)
{
assert(pc);
pc->count = 0;
pc->capacity = INT_SZ;
pc->data = (PeoInfo*)calloc(INT_SZ, sizeof(PeoInfo));
//calloc函数开辟完空间后会自动初始化为0;
if (pc->data == NULL)
{
perror("Init_Contact::calloc");
return;
}
}
通讯录的初始容量是“3”,如果大于3我们就需要进行扩容,我们假设每次扩容2个大小空间,此时就用到了realloc函数:
#define DEFAULT_SZ 2
static void check(Contact* pc)
{
if (pc->count == pc->capacity)
{
PeoInfo* ptr = (PeoInfo*)realloc(pc->data, (pc->capacity + DEFAULT_SZ) * sizeof(PeoInfo));
if (ptr != NULL)
{
pc->data = ptr;
}
else
{
perror("Add_Contact::check::realloc");
return;
}
pc->capacity += DEFAULT_SZ;
printf("增容成功\n");
}
}
void Add_Contact(Contact* pc)
{
assert(pc);
check(pc);
printf("开始添加\n");
printf("请输入添加人的姓名:");
scanf("%s", pc->data[pc->count].name);
printf("请输入添加人的年龄:");
scanf("%d", &(pc->data[pc->count].age));
printf("请输入添加人的性别:");
scanf("%s", pc->data[pc->count].sex);
printf("请输入添加人的电话:");
scanf("%s", pc->data[pc->count].tele);
printf("请输入添加人的地址:");
scanf("%s", pc->data[pc->count].addr);
pc->count++;
printf("添加成功\n");
}
我们在使用动态内存开辟空间以后,最后是需要进行释放的,不然会造成动态内存的泄露,所以,我们在退出通讯录的时候对空间进行释放:
contact.h
void Destory_Contact(Contact* pc);
contact.c
void Destory_Contact(Contact* pc)
{
free(pc->data);
pc->data = NULL;
pc->count = 0;
pc->capacity = 0;
}
动态版本通讯录实现以后,我们会发现,只要退出程序,通讯录的信息就自己销毁了,没有保存下来,接下来我们把他优化成文件版本的,在退出程序之前将通讯录的信息保存下来:
contact.h
void Save_Contact(Contact* pc);
contact.c
void Save_Contact(Contact* pc)
{
assert(pc);
int i = 0;
FILE* pfwrite = fopen("contact.txt", "wb");
if (NULL == pfwrite)
{
perror("Save_Contact::");
return ;
}
for (i = 0; i < pc->count; i++)
{
fwrite(pc->data + i, sizeof(PeoInfo), 1, pfwrite);
}
fclose(pfwrite);
pfwrite = NULL;
}
什么时候将文件信息输出至通讯录呢?当然是初始化的时候,在初始化的时候将文件中的信息导入到通讯录中,因为初始化通讯录容量为3,所以我们在这儿还需要考虑增容的问题,我们将check函数放在文件的开头:
void check(Contact* pc)
{
if (pc->count == pc->capacity)
{
PeoInfo* ptr = (PeoInfo*)realloc(pc->data, (pc->capacity + DEFAULT_SZ) * sizeof(PeoInfo));
if (ptr != NULL)
{
pc->data = ptr;
}
else
{
perror("Add_Contact::check::realloc");
return;
}
pc->capacity += DEFAULT_SZ;
printf("增容成功\n");
}
}
void Load_Contact(Contact* pc)
{
FILE* pfread = fopen("contact.txt", "rb");
if (pfread == NULL)
{
perror("Load_Contact::");
return;
}
PeoInfo tmp = { 0 };
while (fread(&tmp, sizeof(PeoInfo),1, pfread) == 1)
{
check(pc);
pc->data[pc->count] = tmp;
pc->count++;
}
fclose(pfread);
pfread = NULL;
}
void Init_Contact(Contact* pc)
{
assert(pc);
pc->count = 0;
pc->capacity = INT_SZ;
pc->data = (PeoInfo*)calloc(INT_SZ, sizeof(PeoInfo));
//calloc函数开辟完空间后会自动初始化为0;
if (pc->data == NULL)
{
perror("Init_Contact::calloc");
return;
}
Load_Contact(pc);
}
整体代码:
contact.h
#include
#include
#include
#include
#define MAX 1000
#define NAME_MAX 20
#define SEX_MAX 5
#define TELE_MAX 12
#define ADDR_MAX 20
#define INT_SZ 3
#define DEFAULT_SZ 2
enum Point
{
EXIT,
ADD,
DEL,
SEARCH,
MODIFY,
SORT,
PRINT
};
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 data[MAX];//存储联系人的信息
// int count;//存储联系人的数量
//}Contact;
//动态版本
typedef struct Contact
{
PeoInfo* data;//存储联系人的信息
int count;//存储联系人的数量
int capacity;//通讯录的初始容量
}Contact;
//初始化通讯录
void Init_Contact(Contact* pc);
//添加联系人
void Add_Contact(Contact* pc);
//打印联系人
void Print_Contact(Contact* pc);
//删除联系人
void Del_Contact(Contact* pc);
//查找联系人
void Search_Contact(Contact* pc);
//修改联系人
void Modify_Contact(Contact* pc);
//排序所有联系人
void Sort_Contact(Contact* pc);
//释放内存
void Destory_Contact(Contact* pc);
//保存通讯录
void Save_Contact(Contact* pc);
contact.c
#include"contact.h"
//初始化通讯录
//void Init_Contact(Contact* pc)
//{
// assert(pc);
// pc->count = 0;
// memset(pc->data, 0, sizeof(pc->data));
//}
//初始化通讯录
void check(Contact* pc)
{
if (pc->count == pc->capacity)
{
PeoInfo* ptr = (PeoInfo*)realloc(pc->data, (pc->capacity + DEFAULT_SZ) * sizeof(PeoInfo));
if (ptr != NULL)
{
pc->data = ptr;
}
else
{
perror("Add_Contact::check::realloc");
return;
}
pc->capacity += DEFAULT_SZ;
printf("增容成功\n");
}
}
void Load_Contact(Contact* pc)
{
FILE* pfread = fopen("contact.txt", "rb");
if (pfread == NULL)
{
perror("Load_Contact::");
return;
}
PeoInfo tmp = { 0 };
while (fread(&tmp, sizeof(PeoInfo),1, pfread) == 1)
{
check(pc);
pc->data[pc->count] = tmp;
pc->count++;
}
fclose(pfread);
pfread = NULL;
}
void Init_Contact(Contact* pc)
{
assert(pc);
pc->count = 0;
pc->capacity = INT_SZ;
pc->data = (PeoInfo*)calloc(INT_SZ, sizeof(PeoInfo));
//calloc函数开辟完空间后会自动初始化为0;
if (pc->data == NULL)
{
perror("Init_Contact::calloc");
return;
}
Load_Contact(pc);
}
//添加联系人
void Add_Contact(Contact* pc)
{
assert(pc);
check(pc);
printf("开始添加\n");
printf("请输入添加人的姓名:");
scanf("%s", pc->data[pc->count].name);
printf("请输入添加人的年龄:");
scanf("%d", &(pc->data[pc->count].age));
printf("请输入添加人的性别:");
scanf("%s", pc->data[pc->count].sex);
printf("请输入添加人的电话:");
scanf("%s", pc->data[pc->count].tele);
printf("请输入添加人的地址:");
scanf("%s", pc->data[pc->count].addr);
pc->count++;
printf("添加成功\n");
}
//打印联系人
void Print_Contact(Contact* pc)
{
assert(pc);
int i = 0;
printf("%20s %5s %5s %12s %12s\n","姓名", "年龄", "性别", "电话", "地址");
for (i = 0; i < pc->count; i++)
{
printf("%20s %5d %5s %12s %12s\n",pc->data[i].name, pc->data[i].age, pc->data[i].sex,
pc->data[i].tele, pc->data[i].addr);
}
}
//删除联系人
static int find_by_name(Contact* pc, char name[])
{
assert(pc);
int i = 0;
for (i = 0; i < pc->count; i++)
{
if (strcmp(name, pc->data[i].name) == 0)
{
return i;
}
}
return 0;
}
void Del_Contact(Contact* pc)
{
assert(pc);
int i = 0;
//查找联系人
char name[MAX];
printf("请输入要删除的联系人的名字:");
scanf("%s", name);
int pos = find_by_name(pc,name);
if (pos)
{
for (i = pos; i < pc->count - 1; i++)
{
pc->data[i] = pc->data[i + 1];
}
pc->count--;
printf("删除成功\n");
}
else
{
printf("要删除的人不存在\n");
}
}
//查找联系人
void Search_Contact(Contact* pc)
{
assert(pc);
int i = 0;
//查找联系人
char name[MAX];
printf("请输入要查找的联系人的名字:");
scanf("%s", name);
int pos = find_by_name(pc, name);
if (pos)
{
printf("%20s %5s %5s %12s %12s\n", "姓名", "年龄", "性别", "电话", "地址");
printf("%20s %5d %5s %12s %12s\n", pc->data[pos].name, pc->data[pos].age, pc->data[pos].sex,
pc->data[pos].tele, pc->data[pos].addr);
}
else
{
printf("要查找的人不存在\n");
}
}
//修改联系人
void Modify_Contact(Contact* pc)
{
assert(pc);
int i = 0;
//查找联系人
char name[MAX];
printf("请输入要修改的联系人的名字:");
scanf("%s", name);
int pos = find_by_name(pc, name);
if (pos)
{
printf("开始修改\n");
printf("请输入修改人的姓名:");
scanf("%s", pc->data[pos].name);
printf("请输入修改人的年龄:");
scanf("%d", &(pc->data[pos].age));
printf("请输入修改人的性别:");
scanf("%s", pc->data[pos].sex);
printf("请输入修改人的电话:");
scanf("%s", pc->data[pos].tele);
printf("请输入修改人的地址:");
scanf("%s", pc->data[pos].addr);
printf("修改成功\n");
}
else
{
printf("要修改的人不存在\n");
}
}
//排序所以联系人
static int cmp_by_name(const void* e1, const void* e2)
{
return strcmp(((PeoInfo*)e1)->name, ((PeoInfo*)e2)->name);
}
static void swap(char* buf1, char* buf2, size_t width)
{
unsigned int i = 0;
for (i = 0; i < width; i++)
{
char tmp = *buf1;
*buf1 = *buf2;
*buf2 = tmp;
buf1++;
buf2++;
}
}
static void my_bubble_sort(void* base, size_t num, size_t width, int(*cmp)(const void* e1, const void* e2))
{
unsigned int i = 0;
unsigned int j = 0;
for (i = 0; i < num-1; i++)
{
for (j = 0; j < num - 1 - i; j++)
{
if (cmp_by_name((char*)base + j * width, (char*)base + (j + 1) * width )> 0)
{
swap(((char*)base + j * width), ((char*)base + (j + 1) * width), width);
}
}
}
}
void Sort_Contact(Contact* pc)
{
my_bubble_sort(pc->data, pc->count, sizeof(PeoInfo), cmp_by_name);
printf("排序成功\n");
}
//释放内存
void Destory_Contact(Contact* pc)
{
free(pc->data);
pc->data = NULL;
pc->count = 0;
pc->capacity = 0;
}
//保存通讯录
void Save_Contact(Contact* pc)
{
assert(pc);
int i = 0;
FILE* pfwrite = fopen("contact.txt", "wb");
if (NULL == pfwrite)
{
perror("Save_Contact::");
return ;
}
for (i = 0; i < pc->count; i++)
{
fwrite(pc->data + i, sizeof(PeoInfo), 1, pfwrite);
}
fclose(pfwrite);
pfwrite = NULL;
}
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.print ******\n");
printf("************ 0.exit ***********\n");
printf("**************************************\n");
}
int main()
{
Contact con;//创建一个通讯录
Init_Contact(&con);//初始化通讯录
int input = 0;
do
{
menu();
printf("请选择:");
scanf("%d", &input);
switch (input)
{
case ADD:
//添加联系人
Add_Contact(&con);
break;
case DEL:
//删除联系人
Del_Contact(&con);
break;
case SEARCH:
//查找联系人
Search_Contact(&con);
break;
case MODIFY:
//修改联系人
Modify_Contact(&con);
break;
case SORT:
//排序所有联系人
Sort_Contact(&con);
break;
case PRINT:
//打印联系人
Print_Contact(&con);
break;
case EXIT:
//保存通讯录
Save_Contact(&con);
Destory_Contact(&con);
printf("退出通讯录\n");
break;
default:
printf("输入错误,请重新输入\n");
break;
}
} while (input);
return 0;
}