通讯录的动态实现

通讯录的动态实现

模块化编程

分文件
不同模块放在不同的文件下
优点
可维护性:不同模块便于调试某个功能和修改
重用性:常用的功能封装成模块,减少重复利用,提高开发效率
可扩展性:需要增删改现有功能时,模块化编程能够提供更好的扩展性
并行开发:允许多个开发人员并行工作,降低开发过程中的冲突和合并的风险
可测试性:每个模块都是独立的,便于测试功能和性能

通讯录的框架构建

录入联系人信息
由于录入人员一般比较多,需要用创建结构体来创建通讯录结构体和成员信息结构体
录入的信息一般有联系人的姓名、性别、年龄、联系方式、家庭住址

typedef struct peoinfo
{
	char name[MAX_NAME];
	char sex[MAX_SEX];
	int age;
	char tele[MAX_TELE];
	char addr[MAX_ADDR];
}peoinfo;
typedef struct Contact
{
	peoinfo* data;
	int count;//用于记录data对应的下标
	int capacity;

}Contact;

宏定义

#define MAX_NAME 20
#define MAX_SEX 3
#define MAX_TELE 12
#define MAX_ADDR 30

#define MAX_PEONUM 2
#define MAX_COUNT 3

菜单实现

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

通讯录功能声明

void InitContact(Contact* pc);//初始化
void Addpeoinfo(Contact* pc);//增加联系人
void PrintContact(Contact* pc);//打印通讯录
void Delpeoinfo(Contact* pc);//删除联系人
void Findpeoinfo(Contact* pc);//查找联系人
void Modifypeoinfo(Contact* pc);//修改联系人
void SortContact(Contact* pc);//排序通讯录
void DestroyContact(Contact* pc);//销毁通讯录
void SaveContact(Contact* pc);//保留通讯录
void LoadContact(Contact* pc);//加载通讯录
void Check_Capacity(Contact* pc);//检查容量

声明都放在Contact.h头文件里

功能的具体实现

初始化通讯录
void InitContact(Contact* pc)
{
	pc->count = 0;
	pc->data = (peoinfo*)calloc(MAX_PEONUM ,sizeof(peoinfo));//动态内存管理,在堆区分配一块peoinfo*MAX_PEONUM的内存,并且每个字节初始化为0
	// memset(pc->data, 0, sizeof(pc->data));
	pc->capacity = MAX_PEONUM;
	//LoadContact(pc);
}
添加联系人
void Addpeoinfo(Contact* pc)
{
	/*assert(pc);
	if (pc->count = MAX_PEONUM)
	{
		printf("通讯录已满\n");

	}
	else
	{
		printf("请输入名字;>");
		scanf("%s", pc->data[pc->count].name);
		printf("请输入性别;>");
		scanf("%s", pc->data[pc->count].sex);
		printf("请输入年龄;>");
		scanf("%s", pc->data[pc->count].age);
		printf("请输入电话;>");
		scanf("%s", pc->data[pc->count].tele);
		printf("请输入地址;>");
		scanf("%s", pc->data[pc->count].addr);
		pc->count++;
		printf("添加成功\n");
	}*/
	assert(pc);//确定不是空指针
	Check_Capacity(pc);
	printf("请输入名字:>");
	scanf("%s", pc->data[pc->count].name);
	printf("请输入性别:>");
	scanf("%s", pc->data[pc->count].sex);
	printf("请输入年龄:>");
	scanf("%d", &pc->data[pc->count].age);
	printf("请输入电话:>");
	scanf("%s", pc->data[pc->count].tele);
	printf("请输入地址:>");
	scanf("%s", pc->data[pc->count].addr);
	pc->count++;
	printf("添加成功\n");
	

}
删除联系人
void Delpeoinfo(Contact* pc)
{
	assert(pc);
	char name[MAX_NAME];
	printf("请输入要删除的联系人的名字;>");
	scanf("%s", name);
	int pos = FindName(pc, name);
	if (pos == -1)
	{
		printf("通讯录中没有这个人\n");
		return;
	}
	else
	{
		int i = 0;
		for (int i = pos; i < pc->count - 1; i++)
		{
			pc->data[i] = pc->data[i + 1];
		}
		printf("删除成功\n");
		pc->count--;
	}
减容,如果容量减去录入的联系人大于3,减少为两个空间
	if ((pc->capacity - pc->count) > 3)
	{
		peoinfo* ptr = (peoinfo*)realloc(pc->data, (pc->count + 2) * sizeof(peoinfo));
		if (ptr != NULL)
		{
			pc->data = ptr;
			pc->capacity = pc->count + 2;

			printf("通讯录空闲内存大于三个人,减为两个空间,减容成功\n");
		}
		else
		{
			perror("Delpeoinfo");//perror是打印错误信息
		}
	}
}
查找联系人

查找联系人可以通过找到联系人对应名字,并返回下标记录是否找到
需要再封装一个函数

查找名字

static int FindName(const Contact* pc,const char *name)
{
	assert(pc && name);

	for (int pos = 0; pos < pc->count; pos++)
	{
		if (strcmp(pc->data[pos].name, name) == 0)
		{
			return pos;//返回下标
		}
		else
			return -1;
	}
}
void Findpeoinfo(const Contact* pc)
{
	assert(pc);
	char name[MAX_NAME];
	printf("请输入你要查找的联系人的名字:>");
	scanf("%s", name);
	int pos = FindName(pc, name);
	if (pos == -1)
	{
		printf("查无此人\n");
		

	}
	else
	{
		printf("%-15s\t%-5s\t%-5s%-12s\t%-30s\n", "名字", "性别", "年龄", "电话", "地址");
		printf("%-15s\t%-5s\t%-5d%-12s\t%-30s\n",
			pc->data[pos].name,
			pc->data[pos].sex,
			pc->data[pos].age,
			pc->data[pos].tele,
			pc->data[pos].addr);


	}

}
修改联系人
void Modifypeoinfo(Contact* pc) 
{
	assert(pc);
	char name[MAX_NAME];
	printf("请输入你要修改的联系人:>");
	scanf("%s", name);
	int pos = FindName(pc, name);
		if (pos == -1)
		{
			printf("查无此人\n");
			return ;
       	}
		else
		{
			printf("请输入修改后的名字:>");
			scanf("%s", pc->data[pos].name);
			printf("请输入修改后的性别:>");
			scanf("%s", pc->data[pos].sex);
			printf("请输入修改后的年龄:>");
			scanf("%d", &pc->data[pos].age);
			printf("请输入修改后的电话:>");
			scanf("%s", pc->data[pos].tele);
			printf("请输入修改后的地址:>");
			scanf("%s", pc->data[pos].addr);
			
			printf("修改成功\n");
			
		}
}
打印通讯录
void PrintContact(const Contact* pc)
{
	printf("---------------------\n");
	printf("%-15s\t%-5s\t%-5s%-12s\t%-30s\n", "名字", "性别", "年龄", "电话", "地址");
	for (int i = 0; i < pc->count; i++)

	{
		printf("%-15s\t%-5s\t%-5d%-12s\t%-30s\n",
			pc->data[i].name,
			pc->data[i].sex,
			pc->data[i].age,
			pc->data[i].tele,
			pc->data[i].addr);
		
		
	}
	printf("---------------------\n");
}

打印int类型要用%d

排序通讯录
int cmp1(const void* p1, const void* p2)
{
	return strcmp(((peoinfo*)p1)->name, ((peoinfo*)p2)->name);
}
int cmp2(const void* p1, const void* p2)
{
	return strcmp(((peoinfo*)p1)->sex, ((peoinfo*)p2)->sex);
}
int cmp3(const void* p1, const void* p2)
{
	return ((peoinfo*)p1)->age-((peoinfo*)p2)->age;
}
int cmp4(const void* p1, const void* p2)
{
	return strcmp(((peoinfo*)p1)->tele, ((peoinfo*)p2)->tele);
}
int cmp5(const void* p1, const void* p2)
{
	return strcmp(((peoinfo*)p1)->addr, ((peoinfo*)p2)->addr);
}
void sort_by_name(Contact* pc)
{
	qsort(pc->data, pc->count, sizeof(peoinfo),cmp1);
}
void sort_by_sex(Contact* pc)
{
	qsort(pc->data, pc->count, sizeof(peoinfo), cmp2);
}
void sort_by_age(Contact* pc)
{
	qsort(pc->data, pc->count, sizeof(peoinfo), cmp3);
}
void sort_by_tele(Contact* pc)
{
	qsort(pc->data, pc->count, sizeof(peoinfo), cmp4);
}
void sort_by_addr(Contact* pc)
{
	qsort(pc->data, pc->count, sizeof(peoinfo), cmp4);
}
void Sortmenu()
{
	printf("*******************************\n");
	printf("*****  1.name     2.sex   *****\n");
	printf("*****  3.age      4.tele  *****\n");
	printf("*****        5.addr       *****\n");
	printf("*******************************\n");
}
void SortContact(Contact* pc)
{
	assert(pc);
	Sortmenu();
	printf("请选择如何排序;>");
	int num = 0;
		scanf("%d", &num);
		
		if (num==1)
		{
			sort_by_name(pc);
		}
		else if (num==2)
		{
			sort_by_sex(pc);
		}
		else if (num==3)
		{
			sort_by_age(pc);
		}
		else if (num==4)
		{
			sort_by_tele(pc);
		}
		else if (num==5)
		{
			sort_by_addr(pc);
		}
		else
		{
			printf("输入非法,请重新输入\n");
		}
		printf("排序后\n");
		printf("---------------------\n");
		printf("%-15s\t%-5s\t%-5s%-12s\t%-30s\n", "名字", "性别", "年龄", "电话", "地址");
		for (int i = 0; i < pc->count; i++)

		{
			printf("%-15s\t%-5s\t%-5d%-12s\t%-30s\n",
				pc->data[i].name,
				pc->data[i].sex,
				pc->data[i].age,
				pc->data[i].tele,
				pc->data[i].addr);


		}
		printf("---------------------\n");

}
检查容量并扩容
void Check_Capacity(Contact* pc)

{
	if (pc->count == pc->capacity)
	{
		peoinfo* ptr = (peoinfo*)realloc(pc->data, (pc->capacity + MAX_COUNT) * sizeof(peoinfo));
		if (ptr != NULL)
		{
			pc->data= ptr;
			pc->capacity += MAX_COUNT;
			printf("增容成功\n");
		}
		else {
			perror("peoinfo");
			printf("通讯录已满,增容失败无法添加\n");
			return;

		}
	}
}
加载通讯录
void LoadContact(Contact* pc)
{
	FILE* pf = fopen("Contact.txt", "r");
	if (pf == NULL)
	{
		perror("LoadContact");
		return;
	}
	peoinfo temp = { 0 };
	while (fread(&temp, sizeof(peoinfo), 1, pf))
	{
		Check_Capacity(pc);
		pc->data[pc->count] = temp;
		pc->count++;

	}
	fclose(pf);
	pf = NULL;
}
保留通讯录
void SaveContact(Contact* pc) 
{
	FILE* pf = fopen("Contact.txt", "w");//以写的方式打开文件
	if (pf == NULL)
	{
		perror("SaveContact");
		return;
	}
	fwrite(pc->data, sizeof(peoinfo),pc->count,pf);
	fclose(pf);//关闭文件
	pf = NULL;

}

在这里插入图片描述

这里是引用

销毁通讯录

不占用多余的内存空间,养成好习惯

void DestroyContact(Contact* pc)
{
	free(pc->data);
	pc->data = NULL;
	pc->count = 0;
	pc->capacity = 0;
}

完整代码

Contact.h

#pragma once
#include<stdio.h>
#include<string.h>
#include<assert.h>
#include<stdlib.h>
#define MAX_NAME 20
#define MAX_SEX 3
#define MAX_TELE 12
#define MAX_ADDR 30

#define MAX_PEONUM 2
#define MAX_COUNT 3
typedef struct peoinfo
{
	char name[MAX_NAME];
	char sex[MAX_SEX];
	int age;
	char tele[MAX_TELE];
	char addr[MAX_ADDR];
}peoinfo;
typedef struct Contact
{
	peoinfo* data;
	int count;
	int capacity;

}Contact;
void InitContact(Contact* pc);
void Addpeoinfo(Contact* pc);
void PrintContact(Contact* pc);
void Delpeoinfo(Contact* pc);
void Findpeoinfo(Contact* pc);
void Modifypeoinfo(Contact* pc);
void SortContact(Contact* pc);
void DestroyContact(Contact* pc);
void SaveContact(Contact* pc);
void LoadContact(Contact* pc);
void Check_Capacity(Contact* pc);

test.c

#define  _CRT_SECURE_NO_WARNINGS
#include"contact.h"
//1.添加联系人
//2.删除联系人
//3.查找联系人
//排序
//修改联系人
//打印通讯录

void menu()
{
	printf("******************************\n");
	printf("*****  1.add     2.del   *****\n");
	printf("*****  3.find    4.sort  *****\n");
	printf("*****  5.modify  6.print *****\n");
	printf("*****      0.exit    *********\n");
	printf("******************************\n");
}
enum option
{
	EXIT,//无指定默认从0开始
	ADD,
	DEL,
	FIND,
	SORT,
	MODIFY,
	PRINT
};
void test()
{
	
		Contact con;
		InitContact(&con);
		printf("Welcome to use contact!\n");
		int input = 0;
		do
		{
			menu();
			printf("请选择>");
			scanf("%d", &input);
			switch (input)
			{
			case ADD:
				Addpeoinfo(&con);
				break;
			case DEL:
				Delpeoinfo(&con);
				break;
			case FIND:
				Findpeoinfo(&con);
				break;
			case SORT:
				SortContact(&con);
				break;
			case MODIFY:
				Modifypeoinfo(&con);
				break;
			case PRINT:
				PrintContact(&con);
				break;
			case EXIT:
				SaveContact(&con);
				LoadContact(&con);
				printf("退出程序\n");
				break;
			default:
				printf("非法输入,请重`在这里插入代码片`新输入\n");
				break;
			}

		} while (input);
}
int main()
{
	test();
	return 0;
}

Contact.c

#define  _CRT_SECURE_NO_WARNINGS
#include"contact.h"

void InitContact(Contact* pc)
{
	pc->count = 0;
	pc->data = (peoinfo*)calloc(MAX_PEONUM ,sizeof(peoinfo));//动态内存管理,在堆区分配一块peoinfo*MAX_PEONUM的内存,并且每个字节初始化为0
	// memset(pc->data, 0, sizeof(pc->data));
	pc->capacity = MAX_PEONUM;
	LoadContact(pc);
}
void Addpeoinfo(Contact* pc)
{
	assert(pc);
	Check_Capacity(pc);
	printf("请输入名字:>");
	scanf("%s", pc->data[pc->count].name);
	printf("请输入性别:>");
	scanf("%s", pc->data[pc->count].sex);
	printf("请输入年龄:>");
	scanf("%d", &pc->data[pc->count].age);
	printf("请输入电话:>");
	scanf("%s", pc->data[pc->count].tele);
	printf("请输入地址:>");
	scanf("%s", pc->data[pc->count].addr);
	pc->count++;
	printf("添加成功\n");
	

}

void PrintContact(const Contact* pc)
{
	printf("---------------------\n");
	printf("%-15s\t%-5s\t%-5s%-12s\t%-30s\n", "名字", "性别", "年龄", "电话", "地址");
	for (int i = 0; i < pc->count; i++)

	{
		printf("%-15s\t%-5s\t%-5d%-12s\t%-30s\n",
			pc->data[i].name,
			pc->data[i].sex,
			pc->data[i].age,
			pc->data[i].tele,
			pc->data[i].addr);
		
		
	}
	printf("---------------------\n");
}
static int FindName(const Contact* pc,const char *name)
{
	assert(pc && name);

	for (int pos = 0; pos < pc->count; pos++)
	{
		if (strcmp(pc->data[pos].name, name) == 0)
		{
			return pos;//返回下标
		}
		else
			return -1;
	}
}
void Delpeoinfo(Contact* pc)
{
	assert(pc);
	char name[MAX_NAME];
	printf("请输入要删除的联系人的名字;>");
	scanf("%s", name);
	int pos = FindName(pc, name);
	if (pos == -1)
	{
		printf("通讯录中没有这个人\n");
		return;
	}
	else
	{
		int i = 0;
		for (int i = pos; i < pc->count - 1; i++)
		{
			pc->data[i] = pc->data[i + 1];
		}
		printf("删除成功\n");
		pc->count--;
	}

	if ((pc->capacity - pc->count) > 3)
	{
		peoinfo* ptr = (peoinfo*)realloc(pc->data, (pc->count + 2) * sizeof(peoinfo));
		if (ptr != NULL)
		{
			pc->data = ptr;
			pc->capacity = pc->count + 2;

			printf("通讯录空闲内存大于三个人,减为两个空间,减容成功\n");
		}
		else
		{
			perror("Delpeoinfo");
		}
	}
}
void Findpeoinfo(const Contact* pc)
{
	assert(pc);
	char name[MAX_NAME];
	printf("请输入你要查找的联系人的名字:>");
	scanf("%s", name);
	int pos = FindName(pc, name);
	if (pos == -1)
	{
		printf("查无此人\n");
		

	}
	else
	{
		printf("%-15s\t%-5s\t%-5s%-12s\t%-30s\n", "名字", "性别", "年龄", "电话", "地址");
		printf("%-15s\t%-5s\t%-5d%-12s\t%-30s\n",
			pc->data[pos].name,
			pc->data[pos].sex,
			pc->data[pos].age,
			pc->data[pos].tele,
			pc->data[pos].addr);


	}

}
void Modifypeoinfo(Contact* pc) 
{
	assert(pc);
	char name[MAX_NAME];
	printf("请输入你要修改的联系人:>");
	scanf("%s", name);
	int pos = FindName(pc, name);
		if (pos == -1)
		{
			printf("查无此人\n");
			return ;
       	}
		else
		{
			printf("请输入修改后的名字:>");
			scanf("%s", pc->data[pos].name);
			printf("请输入修改后的性别:>");
			scanf("%s", pc->data[pos].sex);
			printf("请输入修改后的年龄:>");
			scanf("%d", &pc->data[pos].age);
			printf("请输入修改后的电话:>");
			scanf("%s", pc->data[pos].tele);
			printf("请输入修改后的地址:>");
			scanf("%s", pc->data[pos].addr);
			
			printf("修改成功\n");
			
		}
}
int cmp1(const void* p1, const void* p2)
{
	return strcmp(((peoinfo*)p1)->name, ((peoinfo*)p2)->name);
}
int cmp2(const void* p1, const void* p2)
{
	return strcmp(((peoinfo*)p1)->sex, ((peoinfo*)p2)->sex);
}
int cmp3(const void* p1, const void* p2)
{
	return ((peoinfo*)p1)->age-((peoinfo*)p2)->age;
}
int cmp4(const void* p1, const void* p2)
{
	return strcmp(((peoinfo*)p1)->tele, ((peoinfo*)p2)->tele);
}
int cmp5(const void* p1, const void* p2)
{
	return strcmp(((peoinfo*)p1)->addr, ((peoinfo*)p2)->addr);
}
void sort_by_name(Contact* pc)
{
	qsort(pc->data, pc->count, sizeof(peoinfo),cmp1);
}
void sort_by_sex(Contact* pc)
{
	qsort(pc->data, pc->count, sizeof(peoinfo), cmp2);
}
void sort_by_age(Contact* pc)
{
	qsort(pc->data, pc->count, sizeof(peoinfo), cmp3);
}
void sort_by_tele(Contact* pc)
{
	qsort(pc->data, pc->count, sizeof(peoinfo), cmp4);
}
void sort_by_addr(Contact* pc)
{
	qsort(pc->data, pc->count, sizeof(peoinfo), cmp4);
}
void Sortmenu()
{
	printf("*******************************\n");
	printf("*****  1.name     2.sex   *****\n");
	printf("*****  3.age      4.tele  *****\n");
	printf("*****        5.addr       *****\n");
	printf("*******************************\n");
}
void SortContact(Contact* pc)
{
	assert(pc);
	Sortmenu();
	printf("请选择如何排序;>");
	int num = 0;
		scanf("%d", &num);
		
		if (num==1)
		{
			sort_by_name(pc);
		}
		else if (num==2)
		{
			sort_by_sex(pc);
		}
		else if (num==3)
		{
			sort_by_age(pc);
		}
		else if (num==4)
		{
			sort_by_tele(pc);
		}
		else if (num==5)
		{
			sort_by_addr(pc);
		}
		else
		{
			printf("输入非法,请重新输入\n");
		}
		printf("排序后\n");
		printf("---------------------\n");
		printf("%-15s\t%-5s\t%-5s%-12s\t%-30s\n", "名字", "性别", "年龄", "电话", "地址");
		for (int i = 0; i < pc->count; i++)

		{
			printf("%-15s\t%-5s\t%-5d%-12s\t%-30s\n",
				pc->data[i].name,
				pc->data[i].sex,
				pc->data[i].age,
				pc->data[i].tele,
				pc->data[i].addr);


		}
		printf("---------------------\n");

}
void DestroyContact(Contact* pc)
{
	free(pc->data);
	pc->data = NULL;
	pc->count = 0;
	pc->capacity = 0;
}
void SaveContact(Contact* pc) 
{
	FILE* pf = fopen("Contact.txt", "w");
	if (pf == NULL)
	{
		perror("SaveContact");
		return;
	}
	fwrite(pc->data, sizeof(peoinfo),pc->count,pf);
	fclose(pf);
	pf = NULL;

}
void LoadContact(Contact* pc)
{
	FILE* pf = fopen("Contact.txt", "r");
	if (pf == NULL)
	{
		perror("LoadContact");
		return;
	}
	peoinfo temp = { 0 };
	while (fread(&temp, sizeof(peoinfo), 1, pf))
	{
		Check_Capacity(pc);
		pc->data[pc->count] = temp;
		pc->count++;

	}
	fclose(pf);
	pf = NULL;
}
void Check_Capacity(Contact* pc)

{
	if (pc->count == pc->capacity)
	{
		peoinfo* ptr = (peoinfo*)realloc(pc->data, (pc->capacity + MAX_COUNT) * sizeof(peoinfo));
		if (ptr != NULL)
		{
			pc->data= ptr;
			pc->capacity += MAX_COUNT;
			printf("增容成功\n");
		}
		else {
			perror("peoinfo");
			printf("通讯录已满,增容失败无法添加\n");
			return;

		}
	}
}

总结

在这里插入图片描述

评论 27
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值