【C进阶】通讯录2.0(文末附原码)

⭐博客主页:️CS semi主页
⭐欢迎关注:点赞收藏+留言
⭐系列专栏:C语言进阶
⭐代码仓库:C Advanced
家人们更新不易,你们的点赞和关注对我而言十分重要,友友们麻烦多多点赞+关注,你们的支持是我创作最大的动力,欢迎友友们私信提问,家人们不要忘记点赞收藏+关注哦!!!

通讯录2.0

  • 前言
  • 一、枚举
  • 二、动态内存
    • (一)更改初始化
    • (二)更改ADD
    • (三)销毁内存空间
    • (四)修改qsort函数
  • 三、文件操作(用fread和fwrite改造)
    • (一)EXIT退出函数
    • (二)InitContact初始化函数
  • 四、结果
  • 五、原码
  • 总结


前言

前面我们写了简单的通讯录,接下来我们将写进阶的通讯录,里面包含枚举,动态内存和文件的操作,是包含了所有进阶的知识,所以,跟着我的脚步,出发!!!


一、枚举

枚举有点很多,比较大的优点是可读性好,当我们进行选择1,2,……后,我们对于这串代码的含义并不明确,而如果直接用枚举显示出来这些名称直接用,可读性非常强,另一个优点是它是有自己本身的类型的,是有类型检查的。更加严谨。
所以,只需要改test.c中的代码即可:
【C进阶】通讯录2.0(文末附原码)_第1张图片
【C进阶】通讯录2.0(文末附原码)_第2张图片


二、动态内存

(一)更改初始化

我们在进行存放联系人信息的时候,我现在有15个朋友,那我设立那么长的空间长时间不用是不是浪费了这么大的空间,那我们现在想的是设立一个动态数组,默认第一次的空间是3个,然后每当不够的时候加2个,空间不够就往上加2个……那我们改造一下:
我们创建动态内存是需要进行结构体声明的,是需要在contact.h里面替换掉原本的Contact的结构体而变成如下图所示(contact.h):
【C进阶】通讯录2.0(文末附原码)_第3张图片

【C进阶】通讯录2.0(文末附原码)_第4张图片

是data所指向的那段另开辟的动态内存空间,为了方便我们使用capcity的作用,我们进行宏定义,将初始化定义为3和将每次自增二定义为2,如下图(在contact.h中):【C进阶】通讯录2.0(文末附原码)_第5张图片
进行定义完这个数组以后,我们需要来对初始化通讯录进行改造,这里就用到了动态数组开辟的方法,为data开辟一块空间(在contact.c中),如下图:
【C进阶】通讯录2.0(文末附原码)_第6张图片

挨个解释解释:
制作一个新的ptr指针,用来存放动态开辟的数组,类型肯定要和pc->data是一样的,因为这样才能实现将ptr首元素指针传给pc,因为ptr是用来维护pc指针的,是要看是不是空指针,至于calloc函数,那就直接上链接,大家去直接看下面博客关于calloc的详细讲解:动态内存 那当然了,为了不影响速度,那就简单介绍一下calloc,它是能够将它所维护的空间初始化为0,然后我们将capcity初始化为3即可。

(二)更改ADD

这是在contact.c中的,上完代码就一步步解释。
【C进阶】通讯录2.0(文末附原码)_第7张图片

我们将这个动态开辟内存封装成一个函数,在函数内部,我们需要判断的是已经满容量了以后,我们需要做的操作,要增容怎么办,realloc解决一切烦恼,大家也可以看博客,也可以听我先简单陈述:内存函数 realloc函数的解释是pc->data是所需增加的空间,后面的是总的数(增加的空间加上原本的空间)。和前面一样的道理,和王者荣耀里面的元歌一样,分身先往前走,前面安全了再让真身走,前面有危险,分身消失,真身保持不变。

(三)销毁内存空间

我们在学习动态数组开辟的时候,是有free这个函数的,是释放开辟的空间的函数,而在制作这套通讯录的动态数组中,我们同样也需要来一个销毁这个动态内存的空间的操作,那我们就定义一个Destory函数吧!
test.c
【C进阶】通讯录2.0(文末附原码)_第8张图片
contact.h
【C进阶】通讯录2.0(文末附原码)_第9张图片
contact.c
【C进阶】通讯录2.0(文末附原码)_第10张图片
这串代码总体来讲就是将这些值全部变为空或者0。

(四)修改qsort函数

我发现如果qsort函数一直是保持这样不变的话,是肯定不正确的,我通过调试和各项参考发现如果还按照老版本的qsort函数发现数据都给我吞了,和Empty函数怎么一样了,当即我就慌了神,但是经过一段时间的思考,&con本来就是在结构体内开辟的一个数组,已经是被维护的数组,而con.data是指向某一个数组,因为我们创立的的data是指向某一个数组的,所以就不能是&con了,需要找到data的数组。
在这里插入图片描述
到这里先给个整体的代码,下面将进行文件的操作,有很多改编不需要文件的操作那就这里先放一下动态数组的版本吧!
test.c

#include"contact.h"

void menu()
{
	printf("************************************\n");
	printf("*******  1.add     2.del     *******\n");
	printf("*******  3.search  4.modify  *******\n");
	printf("*******  5.show    6.sort    *******\n");
	printf("*******  7.empty   0.exit    *******\n");
	printf("************************************\n");
}

enum Option {
	EXIT,//0
	ADD, //1
	DEL, //2
	SEARCH,
	MODIFY,
	SHOW,
	SORT,
	EMPTY
};

int main()
{
	int input = 0;
	//创建通讯录
	Contact con;
	//初始化通讯录
	InitContact(&con);

	do {
		menu();
		printf("请选择:>");
		scanf("%d", &input);
		switch (input)
		{
		case ADD:
			AddContact(&con);
			break;
		case DEL:
			DelContact(&con);
			Sleep(1000);
			break;
		case SEARCH:
			SearchContact(&con);
			break;
		case MODIFY:
			ModifyContact(&con);
			Sleep(500);
			break;
		case SHOW:
			ShowContact(&con);
			break;
		case SORT://&con
			qsort(con.data, con.sz, sizeof(con.data[0]), ContactSortName);
			printf("排序成功\n");
			Sleep(1000);
			break;
		case EMPTY:
			EmptyContact(&con);
			printf("已全部清空\n");
			Sleep(1000);
			break;
		case EXIT:
			Destory(&con);
			printf("退出通讯录\n");
			break;
		default:
			printf("选择错误,请重新选择\n");
			break;
		}
	} while (input);
	return 0;
}

contact.h

#define MAX 1000
#define NAMEMAX 20
#define SEWXMAX 5
#define ADDRMAX 30
#define TELEMAX 12

#define DEFAULTSZ 3
#define INCSZ 2

#include
#include
#include
#include
#include

//人的信息
typedef struct PeoInfo {
	char name[NAMEMAX];
	int age;
	char sex[SEWXMAX];
	char addr[ADDRMAX];
	char tele[TELEMAX];
}PeoInfo;

静态数组版本
//typedef struct Contact {
//	//创建通讯录
//	PeoInfo data[MAX];//存放人的信息
//	int sz;//当前已经放的信息的个数
//}Contact;


//动态数组版本
typedef struct Contact {
	//创建通讯录
	PeoInfo* data;//指向存放人的信息的空间
	int sz;//当前已经放的信息的个数
	int capacity;//当前通讯录的最大容量
}Contact;



//初始化通讯录
void InitContact(Contact* pc);

//增加联系人
void AddContact(Contact* pc);

//显示通讯录里的联系人
void ShowContact(const Contact* pc);

//删除联系人
void DelContact(Contact* pc);

//查找联系人
void SearchContact(const Contact* pc);

//修改指定联系人信息
void ModifyContact(Contact* pc);

//排序
int ContactSortName(void* e1, void* e2);

//清空
void EmptyContact(Contact* pc);

//销毁通讯录内存
void Destory(Contact* pc);

contact.c

//负责实现声明

#include"contact.h"

静态版本
实现初始化通讯录
//void InitContact(Contact* pc) {
//	assert(pc);
//	pc->sz = 0;
//	memset(pc->data, 0, sizeof(pc->data));//传过来的是地址,根据地址找到了data数组,算的是data数组的总大小
//}

//动态版本
//实现初始化通讯录
void InitContact(Contact* pc) {
	assert(pc);
	pc->sz = 0;
	PeoInfo* ptr = (PeoInfo*)calloc(DEFAULTSZ,sizeof(PeoInfo) );
	if (ptr == NULL) {
		perror("calloc::InitContact");
		return;
	}
	pc->data = ptr;
	pc->capacity = DEFAULTSZ;
}

静态版本
增加联系人
//void AddContact(Contact* pc) {
//	assert(pc);
//	if (pc->sz == MAX) {
//		printf("通讯录已满,无法添加联系人\n");
//		return;
//	}
//	//增加一个人信息
//	printf("请输入名字>");
//	scanf("%s", pc->data[pc->sz].name);
//	printf("请输入年龄>");
//	scanf("%d", &(pc->data[pc->sz].age));
//	printf("请输入性别>");
//	scanf("%s", pc->data[pc->sz].sex);
//	printf("请输入地址>");
//	scanf("%s", pc->data[pc->sz].addr);
//	printf("请输入电话>");
//	scanf("%s", pc->data[pc->sz].tele);
//	pc->sz++;
//}

//动态版本
//增加联系人
void check_capacity(Contact* pc) {
	if (pc->sz == pc->capacity) {
		//增容
		PeoInfo* ptr = (PeoInfo*)realloc(pc->data, sizeof(PeoInfo) * (pc->capacity + INCSZ));
		if (ptr == NULL) {
			perror("realloc::check_capacity");
			return;
		}
		pc->data = ptr;
		pc->capacity += INCSZ;
	}
}
void AddContact(Contact* pc) {
	assert(pc);
	check_capacity(pc);

	//增加一个人信息
	printf("请输入名字>");
	scanf("%s", pc->data[pc->sz].name);
	printf("请输入年龄>");
	scanf("%d", &(pc->data[pc->sz].age));
	printf("请输入性别>");
	scanf("%s", pc->data[pc->sz].sex);
	printf("请输入地址>");
	scanf("%s", pc->data[pc->sz].addr);
	printf("请输入电话>");
	scanf("%s", pc->data[pc->sz].tele);
	pc->sz++;
}


//显示通讯录里的信息
void ShowContact(const Contact* pc) {
	assert(pc);
	int i = 0;
	printf("%-20s\t%-4s\t%-5s\t%-20s\t%-12s\n", "name", "age", "sex", "address", "telephone");
	for (i = 0; i < pc->sz; i++) {
		printf("%-20s\t%-4d\t%-5s\t%-20s\t%-12s\n", pc->data[i].name,
			pc->data[i].age,
			pc->data[i].sex,
			pc->data[i].addr,
			pc->data[i].tele);
	}
}


int FindByName(const Contact* pc, char name[]) {
	assert(pc);
	int i = 0;
	int pos = 0;
	for (i = 0; i < pc->sz; i++) {
		if (strcmp(pc->data[i].name, name) == 0) {
			pos = i;
			return i;
		}
	}
	return -1;
}
//删除联系人
void DelContact(Contact* pc) {
	assert(pc);
	char name[NAMEMAX] = { 0 };
	//没有联系人不删除
	if (pc->sz == 0) {
		printf("通讯录为空,无法删除\n");
		return;
	}
	//删除联系人
	//找到要删除的人
	printf("请输入要删除的人的名字:>");
	scanf("%s", name);
	//查找
	int ret = FindByName(pc, name);
	if (-1 == ret) {
		printf("查无此人\n");
		return;
	}
	else {
		//删除
		int i = 0;
		for (i = ret; i < pc->sz - 1; i++) {
			pc->data[i] = pc->data[i + 1];
		}
		pc->sz--;
		printf("删除成功\n");
	}
}

//查找联系人
void SearchContact(const Contact* pc) {
	assert(pc);
	char name[NAMEMAX] = { 0 };
	printf("请输入要查找人的名字>");
	scanf("%s", name);
	int ret = FindByName(pc, name);
	if (-1 == ret) {
		printf("查无此人\n");
		return;
	}
	else {
		//打印信息
		printf("%-20s\t%-4s\t%-5s\t%-20s\t%-12s\n", "name", "age", "sex", "address", "telephone");
		printf("%-20s\t%-4d\t%-5s\t%-20s\t%-12s\n", pc->data[ret].name,
			pc->data[ret].age,
			pc->data[ret].sex,
			pc->data[ret].addr,
			pc->data[ret].tele);
	}
}

//修改指定联系人
void ModifyContact(Contact* pc) {
	assert(pc);
	//先找这个联系人
	char name[NAMEMAX] = { 0 };
	printf("请输入要修改人的名字>");
	scanf("%s", name);
	int ret = FindByName(pc, name);
	if (-1 == ret) {
		printf("查无此人\n");
		return;
	}
	else {
		//信息重新录入
		printf("请输入名字>");
		scanf("%s", pc->data[ret].name);
		printf("请输入年龄>");
		scanf("%d", &(pc->data[ret].age));
		printf("请输入性别>");
		scanf("%s", pc->data[ret].sex);
		printf("请输入地址>");
		scanf("%s", pc->data[ret].addr);
		printf("请输入电话>");
		scanf("%s", pc->data[ret].tele);
		printf("修改完成\n");
	}
}

//排序
int ContactSortName(void* e1, void* e2) {
	assert(e1 && e2);
	return strcmp((Contact*)e1, (Contact*)e2);
}

//清空
void EmptyContact(Contact* pc) {
	assert(pc);
	pc->sz = 0;
	memset(pc->data, 0, sizeof(pc->data));
}

//销毁通讯录内存
void Destory(Contact* pc) {
	free(pc->data);
	pc->data = NULL;
	pc->capacity = 0;
	pc->sz = 0;
	pc = NULL;
}

三、文件操作(用fread和fwrite改造)

(一)EXIT退出函数

既然我们要大刀阔斧地朝向代码进行改编,势必要把它放到文件里面,那就我文件执行完我再放吧,这毕竟我立马存到文件里面万一之后要删删改改呢?所以我们在EXIT函数进行增加添加文件项:
test.c:
【C进阶】通讯录2.0(文末附原码)_第11张图片

contact.c:
首先我们需要在相对应的文件夹中创立一个好取名字的文件名并在contact.c文件中进行引用,这里选择的是fwrite,是因为在计算机中写的是二进制的“流”,更加的好用。
【C进阶】通讯录2.0(文末附原码)_第12张图片
【C进阶】通讯录2.0(文末附原码)_第13张图片

这里是需要认清楚fwrite函数的用法,大家可以看下面这篇博客:
文件操作简单而言就是找到数组地址,字节长度,元素个数,文件流。

(二)InitContact初始化函数

contact.c:
【C进阶】通讯录2.0(文末附原码)_第14张图片
我们读到文件里面需要加载文件信息到通讯录,我们直接封装一个函数进行操作(还在contact.c):

【C进阶】通讯录2.0(文末附原码)_第15张图片
这里形式有些许复杂,我们需要了解清楚fread函数的具体作用,再根据增容的变化值进行读数据。


四、结果

这是添加完的操作:

这是退出通讯录,保存完文件的操作:

这是再次打开调试台显示数据被保存的操作:

五、原码

test.c

#include"contact.h"

void menu()
{
	printf("************************************\n");
	printf("*******  1.add     2.del     *******\n");
	printf("*******  3.search  4.modify  *******\n");
	printf("*******  5.show    6.sort    *******\n");
	printf("*******  7.empty   0.exit    *******\n");
	printf("************************************\n");
}

enum Option {
	EXIT,//0
	ADD, //1
	DEL, //2
	SEARCH,
	MODIFY,
	SHOW,
	SORT,
	EMPTY
};

int main()
{
	int input = 0;
	//创建通讯录
	Contact con;
	//初始化通讯录
	InitContact(&con);

	do {
		menu();
		printf("请选择:>");
		scanf("%d", &input);
		switch (input)
		{
		case ADD:
			AddContact(&con);
			break;
		case DEL:
			DelContact(&con);
			Sleep(1000);
			break;
		case SEARCH:
			SearchContact(&con);
			break;
		case MODIFY:
			ModifyContact(&con);
			Sleep(500);
			break;
		case SHOW:
			ShowContact(&con);
			break;
		case SORT://&con
			qsort(con.data, con.sz, sizeof(con.data[0]), ContactSortName);
			printf("排序成功\n");
			Sleep(1000);
			break;
		case EMPTY:
			EmptyContact(&con);
			printf("已全部清空\n");
			Sleep(1000);
			break;
		case EXIT:
			//保存通讯录信息到文件中
			SaveContact(&con);
			Destory(&con);
			printf("退出通讯录\n");
			break;
		default:
			printf("选择错误,请重新选择\n");
			break;
		}
	} while (input);
	return 0;
}

contact.h

#define MAX 1000
#define NAMEMAX 20
#define SEWXMAX 5
#define ADDRMAX 30
#define TELEMAX 12

#define DEFAULTSZ 3
#define INCSZ 2

#include
#include
#include
#include
#include

//人的信息
typedef struct PeoInfo {
	char name[NAMEMAX];
	int age;
	char sex[SEWXMAX];
	char addr[ADDRMAX];
	char tele[TELEMAX];
}PeoInfo;

静态数组版本
//typedef struct Contact {
//	//创建通讯录
//	PeoInfo data[MAX];//存放人的信息
//	int sz;//当前已经放的信息的个数
//}Contact;


//动态数组版本
typedef struct Contact {
	//创建通讯录
	PeoInfo* data;//指向存放人的信息的空间
	int sz;//当前已经放的信息的个数
	int capacity;//当前通讯录的最大容量
}Contact;



//初始化通讯录
void InitContact(Contact* pc);

//增加联系人
void AddContact(Contact* pc);

//显示通讯录里的联系人
void ShowContact(const Contact* pc);

//删除联系人
void DelContact(Contact* pc);

//查找联系人
void SearchContact(const Contact* pc);

//修改指定联系人信息
void ModifyContact(Contact* pc);

//排序
int ContactSortName(void* e1, void* e2);

//清空
void EmptyContact(Contact* pc);

//销毁通讯录内存
void Destory(Contact* pc);

//保存通讯录中的信息到文件中
void SaveContact(Contact* pc);

//加载文件信息到通讯录
void LoadContact(Contact* pc);

contact.c

//负责实现声明

#include"contact.h"

静态版本
实现初始化通讯录
//void InitContact(Contact* pc) {
//	assert(pc);
//	pc->sz = 0;
//	memset(pc->data, 0, sizeof(pc->data));//传过来的是地址,根据地址找到了data数组,算的是data数组的总大小
//}

//动态版本
//实现初始化通讯录
void InitContact(Contact* pc) {
	assert(pc);
	pc->sz = 0;
	PeoInfo* ptr = (PeoInfo*)calloc(DEFAULTSZ, sizeof(PeoInfo));
	if (ptr == NULL) {
		perror("calloc::InitContact");
		return;
	}
	pc->data = ptr;
	pc->capacity = DEFAULTSZ;

	//加载文件信息到通讯录
	LoadContact(pc);
}

静态版本
增加联系人
//void AddContact(Contact* pc) {
//	assert(pc);
//	if (pc->sz == MAX) {
//		printf("通讯录已满,无法添加联系人\n");
//		return;
//	}
//	//增加一个人信息
//	printf("请输入名字>");
//	scanf("%s", pc->data[pc->sz].name);
//	printf("请输入年龄>");
//	scanf("%d", &(pc->data[pc->sz].age));
//	printf("请输入性别>");
//	scanf("%s", pc->data[pc->sz].sex);
//	printf("请输入地址>");
//	scanf("%s", pc->data[pc->sz].addr);
//	printf("请输入电话>");
//	scanf("%s", pc->data[pc->sz].tele);
//	pc->sz++;
//}

//动态版本
//增加联系人
void check_capacity(Contact* pc) {
	if (pc->sz == pc->capacity) {
		//增容
		PeoInfo* ptr = (PeoInfo*)realloc(pc->data, sizeof(PeoInfo) * (pc->capacity + INCSZ));
		if (ptr == NULL) {
			perror("realloc::check_capacity");
			return;
		}
		pc->data = ptr;
		pc->capacity += INCSZ;
	}
}
void AddContact(Contact* pc) {
	assert(pc);
	check_capacity(pc);

	//增加一个人信息
	printf("请输入名字>");
	scanf("%s", pc->data[pc->sz].name);
	printf("请输入年龄>");
	scanf("%d", &(pc->data[pc->sz].age));
	printf("请输入性别>");
	scanf("%s", pc->data[pc->sz].sex);
	printf("请输入地址>");
	scanf("%s", pc->data[pc->sz].addr);
	printf("请输入电话>");
	scanf("%s", pc->data[pc->sz].tele);
	pc->sz++;
}


//显示通讯录里的信息
void ShowContact(const Contact* pc) {
	assert(pc);
	int i = 0;
	printf("%-20s\t%-4s\t%-5s\t%-20s\t%-12s\n", "name", "age", "sex", "address", "telephone");
	for (i = 0; i < pc->sz; i++) {
		printf("%-20s\t%-4d\t%-5s\t%-20s\t%-12s\n", pc->data[i].name,
			pc->data[i].age,
			pc->data[i].sex,
			pc->data[i].addr,
			pc->data[i].tele);
	}
}


int FindByName(const Contact* pc, char name[]) {
	assert(pc);
	int i = 0;
	int pos = 0;
	for (i = 0; i < pc->sz; i++) {
		if (strcmp(pc->data[i].name, name) == 0) {
			pos = i;
			return i;
		}
	}
	return -1;
}
//删除联系人
void DelContact(Contact* pc) {
	assert(pc);
	char name[NAMEMAX] = { 0 };
	//没有联系人不删除
	if (pc->sz == 0) {
		printf("通讯录为空,无法删除\n");
		return;
	}
	//删除联系人
	//找到要删除的人
	printf("请输入要删除的人的名字:>");
	scanf("%s", name);
	//查找
	int ret = FindByName(pc, name);
	if (-1 == ret) {
		printf("查无此人\n");
		return;
	}
	else {
		//删除
		int i = 0;
		for (i = ret; i < pc->sz - 1; i++) {
			pc->data[i] = pc->data[i + 1];
		}
		pc->sz--;
		printf("删除成功\n");
	}
}

//查找联系人
void SearchContact(const Contact* pc) {
	assert(pc);
	char name[NAMEMAX] = { 0 };
	printf("请输入要查找人的名字>");
	scanf("%s", name);
	int ret = FindByName(pc, name);
	if (-1 == ret) {
		printf("查无此人\n");
		return;
	}
	else {
		//打印信息
		printf("%-20s\t%-4s\t%-5s\t%-20s\t%-12s\n", "name", "age", "sex", "address", "telephone");
		printf("%-20s\t%-4d\t%-5s\t%-20s\t%-12s\n", pc->data[ret].name,
			pc->data[ret].age,
			pc->data[ret].sex,
			pc->data[ret].addr,
			pc->data[ret].tele);
	}
}

//修改指定联系人
void ModifyContact(Contact* pc) {
	assert(pc);
	//先找这个联系人
	char name[NAMEMAX] = { 0 };
	printf("请输入要修改人的名字>");
	scanf("%s", name);
	int ret = FindByName(pc, name);
	if (-1 == ret) {
		printf("查无此人\n");
		return;
	}
	else {
		//信息重新录入
		printf("请输入名字>");
		scanf("%s", pc->data[ret].name);
		printf("请输入年龄>");
		scanf("%d", &(pc->data[ret].age));
		printf("请输入性别>");
		scanf("%s", pc->data[ret].sex);
		printf("请输入地址>");
		scanf("%s", pc->data[ret].addr);
		printf("请输入电话>");
		scanf("%s", pc->data[ret].tele);
		printf("修改完成\n");
	}
}

//排序
int ContactSortName(void* e1, void* e2) {
	assert(e1 && e2);
	return strcmp((Contact*)e1, (Contact*)e2);
}

//清空
void EmptyContact(Contact* pc) {
	assert(pc);
	pc->sz = 0;
	memset(pc->data, 0, sizeof(pc->data));
}

//销毁通讯录内存
void Destory(Contact* pc) {
	free(pc->data);
	pc->data = NULL;
	pc->capacity = 0;
	pc->sz = 0;
	pc = NULL;
}

//保存通讯录中的信息到文件中
void SaveContact(Contact* pc) {
	assert(pc);
	//写数据
	//打开文件
	FILE* pf = fopen("D:\\GITTE chuantimu\\test_1_24(【C进阶】文件操作3)\\contact.txt", "wb");
	if (NULL == pf) {
		perror("SaveContact::fopen");
		return;
	}
	else {
		//写数据
		int i = 0;
		for (i = 0; i < pc->sz; i++) {
			fwrite(&(pc->data[i]), sizeof(PeoInfo), 1, pf);
		}
		//关闭文件
		fclose(pf);
		pf = NULL;
		printf("保存数据成功\n");
	}
}

//加载文件信息到通讯录
void LoadContact(Contact* pc) {
	assert(pc);
	//读数据
	//1.打开文件
	FILE* pf = fopen("D:\\GITTE chuantimu\\test_1_24(【C进阶】文件操作3)\\contact.txt", "rb");
	if (pf == NULL) {
		perror("LoadContact::fopen");
		return;
	}
	else {
		//2.读数据
		PeoInfo tmp = { 0 };
		int i = 0;
		while (fread(&tmp, sizeof(PeoInfo), 1, pf)) {
			//增容
			check_capacity(pc);
			pc->data[i] = tmp;
			pc->sz++;
			i++;
		}
		fclose(pf);
		pf = NULL;
	}
}

总结

这次的改编算是比较完美了,但肯定还有美中不足的地方,就是排列可以更加多元化一些,如果仅仅是qsort排序是很方便但也需要体验不同的排序方式,总而言之,这就是最终的通讯录版本了~~


客官,来个三连支持一下吧!!!

你可能感兴趣的:(C语言进阶,c语言,开发语言,数据结构,算法,c++)