c语言实现通讯录

目录

一.前言

二.通讯录的实现

1.在通讯录实现功能前进行的准备

(1)展示菜单

(2)有关联系人结构体的创建

(3)主函数部分

2.通讯录功能的实现

(1)对通讯录进行初始化

(2)增加联系人信息

(3)显示通讯录信息​编辑

(4)删除指定联系人信息​编辑

(5)查找指定联系人​编辑

(6)修改指定联系人的所有信息

(7)对通讯录进行排序

三.对通讯录进行优化

1.我们可以对通讯录结构体进行优化

2.对结构体初始化并分配内存

3.增容

4.释放内存

四.总结(附代码)


一.前言

        本文将用c语言实现通讯录的功能。包括(增加联系人信息,删除联系人信息,查找指定联系人信息,修改指定联系人信息,显示通讯录联系人信息,以名字排序所有联系人)。

二.通讯录的实现

1.在通讯录实现功能前进行的准备

(1)展示菜单

首先需要一个美观的菜单页面来面向我们的服务群体。

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

(2)有关联系人结构体的创建
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];     //存放100个人的信息
	int sz;			   //记录通讯录存放的人的信息个数
}Contact;

如上代码所示,第一个结构体为一个联系人的信息汇总,第二个结构体为通讯录总体。

#define NAME_MAX 20
#define SEX_MAX	 5
#define TELE_MAX 12
#define ADDR_MAX 30
#define MAX 1000

利用宏来确定最大值利于对通讯录容量的修改。

(3)主函数部分
enum Option           //枚举常量
{
	EXIT,
	ADD,
	DEL,
	SEARCH,
	MODIFY,
	SHOW,
	SORT
};

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);
			break;
		case SEARCH:                                          //查
			SearchContact(&con);
			break;
		case MODIFY:                                          //改
			ModifyContact(&con);
			break;
		case SHOW:                                            //显示
			ShowContact(&con);
			break;
		case SORT:                                            //排序
			SortContact(&con);
			break;
		case EXIT:                                            //退出
			printf("退出通讯录\n");
			break;
		default:
			printf("选择错误,重新选择\n");
			break;
		};

		


	} while (input);
	return 0;
}

2.通讯录功能的实现

(1)对通讯录进行初始化

void InitContact(Contact* pc)
{
	assert(pc);

	pc->sz = 0;
	memset(pc->data, 0, sizeof(pc->data));

}//初始化通讯录
(2)增加联系人信息

我们可以创建增加联系人的函数,以此来增添联系人信息。

void AddContact(Contact* pc)
{
	assert(pc);


	if (pc->sz ==1000)
	{
		printf("通讯录储存信息已满");
		return;
	}
	else
	printf("请输入名字:");
	scanf("%s", &pc->data[pc->sz].name);
	printf("请输入性别:");
	scanf("%s", &pc->data[pc->sz].sex);
	printf("请输入年龄:");
	scanf("%d", &pc->data[pc->sz].age);
	printf("请输入电话:");
	scanf("%s", &pc->data[pc->sz].tele);
	printf("请输入地址:");
	scanf("%s", &pc->data[pc->sz].addr);

	pc->sz++;
	printf("通讯录增加成功!!!\n");
}

(3)显示通讯录信息

为了方便我们知道自己是否正确增添联系人信息,我们可以将通讯录打印出来。

void ShowContact(const Contact* pc)
{
	assert(pc);

	if (pc->sz == 0)
	{
		printf("通讯录为空,无需打印");
		return;
	}
	
	printf("%-20s%-5s%-5s%-12s%-30s\n", "姓名","年龄","性别" ,"电话", "住址");

	for (int i = 0; i < pc->sz; i++)
	{
		printf("%-20s%-5d%-5s%-12s%-30s\n",pc->data[i].name,
										pc->data[i].age,
										pc->data[i].sex,
										pc->data[i].tele,
										pc->data[i].addr);
	}
}
(4)删除指定联系人信息

如何找到指定联系人信息来供我们删除是个问题,所以我们应先构建一个函数供咱们查找联系人。如用姓名来查找

int FindByName(Contact* pc,char name[])
{
	assert(pc);
	for (int i = 0; i < pc->sz; i++)
	{
		if (strcmp(pc->data[i].name, name) == 0)
		{
			return i;
		}
	}
	return -1;
}

如果找到联系人会返回它的位置,接下来删除信息会更简便。

因此剩余的该函数的主体为

void DelContact(Contact* pc)
{
	char name[NAME_MAX];
	assert(pc);
	if (pc->sz == 0)
	{
		printf("通讯录为空,无法删除\n");
		return;
	}


	printf("请输入被删除人的姓名:");
	scanf("%s", name);

	//查找是否存在

	int ret = FindByName(pc, name);
	if (ret == -1)

	{
		printf("要删除的人不存在\n");
		return;
	}
	//删除这个人
	int i = 0;
	for (i = ret; i < pc->sz - 1; i++)
	{
		pc->data[i] = pc->data[i + 1];
		
	}
	pc->sz--;
	printf("删除成功\n");
	
}
(5)查找指定联系人

根据删除联系人部分的查找代码,我们可以很轻松写出查找函数功能。

void SearchContact(Contact* pc)
{
	char name[NAME_MAX];
	assert(pc);
	printf("请输入查找的联系人姓名:");
	scanf("%s", name);

	//查找是否存在

	int ret = FindByName(pc, name);
	if (ret == -1)
	{
		printf("要查找的人不存在\n");
		return;
	}
	printf("%-20s%-5s%-5s%-12s%-30s\n", "姓名", "年龄", "性别", "电话", "住址");
	printf("%-20s%-5d%-5s%-12s%-30s\n", pc->data[ret].name,
		pc->data[ret].age,
		pc->data[ret].sex,
		pc->data[ret].tele,
		pc->data[ret].addr);

}
int FindByName(Contact* pc,char name[])
{
	assert(pc);
	for (int i = 0; i < pc->sz; i++)
	{
		if (strcmp(pc->data[i].name, name) == 0)
		{
			return i;
		}
	}
	return -1;
}
(6)修改指定联系人的所有信息

依靠FindByName函数的查找可以实现修改功能

int FindByName(Contact* pc,char name[])
{
	assert(pc);
	for (int i = 0; i < pc->sz; i++)
	{
		if (strcmp(pc->data[i].name, name) == 0)
		{
			return i;
		}
	}
	return -1;
}
void ModifyContact(Contact* pc)
{

	char name[NAME_MAX];
	assert(pc);
	printf("请输入修改的联系人姓名:");
	scanf("%s", name);

	int ret = FindByName(pc, name);
	if (ret == -1)
	{
		printf("要修改的人不存在\n");
		return;
	}

	printf("请输入名字:");
	scanf("%s", &pc->data[ret].name);
	printf("请输入性别:");
	scanf("%s", &pc->data[ret].sex);
	printf("请输入年龄:");
	scanf("%d", &pc->data[ret].age);
	printf("请输入电话:");
	scanf("%s", &pc->data[ret].tele);
	printf("请输入地址:");
	scanf("%s", &pc->data[ret].addr);
	printf("修改成功!!\n");
}
(7)对通讯录进行排序

根据冒泡排序的思想,我们可以写出排序功能的函数。

void SortContact(Contact* pc)
{
	assert(pc);

	if (pc->sz == 0)
	{
		printf("通讯录为空,无需排序");
		return;
	}
	int i = 0;
	PeoInfo temp;
	for (i = 0; i < pc->sz - 1; i++)
	{

		for (int j = 0; j < pc->sz - i - 1; j++)
		{
			if ((strcmp(pc->data[j].name, pc->data[j + 1].name)) > 0)
			{
				temp = pc->data[j + 1];
				pc->data[j + 1] = pc->data[j];
				pc->data[j] = temp;
			}
		}

	}
	printf("排序成功!!!\n");
}

综上我们的通讯录就实现了!!!

三.对通讯录进行优化

        对于我们设定的通讯录大小为1000,我们发现如果只存储3个联系人会对空间造成不必要的浪费,而对于对超出1000人的通讯录的储存则存在无法储存的问题。因此:

1.我们可以对通讯录结构体进行优化

既然是动态内存存储,我们可以将PeoInfo数组改为指针,为我们开辟动态内存空间做准备。

//动态版本
typedef struct Contact
{
	PeoInfo* data;                //存放个人的信息
	int sz;			              //记录通讯录存放的人的信息个数
	int capacity;                 //通讯录容量

}Contact;

2.对结构体初始化并分配内存

#define DEFAULE_SZ 3

void InitContact(Contact* pc)
{
	assert(pc);//断言

	pc->sz = 0;
	pc->capacity = DEFAULE_SZ;
	pc->data= calloc( pc->capacity , sizeof(PeoInfo));
	if (pc->data == NULL)
	{
		perror("InitContact->calloc");

		return;
	}

}

3.增容

当通讯录容量满了时,我们可以进行增容来扩充,每一次扩充两个联系人信息的储存空间。

#define DEFAULE_INC 2 


void CheckCapacity(Contact* pc)
{
	assert(pc);
	if (pc->sz == pc->capacity)
	{
		PeoInfo* ptr = (PeoInfo*)realloc(pc->data, (pc->capacity + DEFAULE_INC) * sizeof(PeoInfo));
		if (ptr != NULL)
		{
			pc->data = ptr;
			pc->capacity += DEFAULE_INC;
			printf("增容成功!!\n");
		}
		else
		{
			perror("AddContact->realloc");
			return;
		}
	}
	
}

4.释放内存

对于动态内存的分配,程序关闭前必须进行销毁内存空间的操作。

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

四.总结(附代码)

        以上为实现一个通讯录系统的大致过程。对于通讯录优化的过程中,大家记住结束程序时要释放内存防止内存泄漏。以上内容仅供参考如有雷同纯属巧合。

#pragma once
//类型的声明
#define NAME_MAX 20
#define SEX_MAX	 5
#define TELE_MAX 12
#define ADDR_MAX 30

#define MAX 1000


#define DEFAULE_SZ 3
#define DEFAULE_INC 2

#include<stdio.h>
#include<string.h>
#include<assert.h>
#include<stdlib.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];     //存放100个人的信息
//	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(Contact* pc);

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

//对通讯录进行排序
void SortContact(Contact* pc);



//主要功能代码区域


//静态版本
//void InitContact(Contact* pc)
//{
//	assert(pc);
//
//	pc->sz = 0;
//	memset(pc->data, 0, sizeof(pc->data));
//
//}

void InitContact(Contact* pc)
{
	assert(pc);

	pc->sz = 0;
	pc->capacity = DEFAULE_SZ;
	pc->data= calloc( pc->capacity , sizeof(PeoInfo));
	if (pc->data == NULL)
	{
		perror("InitContact->calloc");

		return;
	}

}

//静态版本
//void AddContact(Contact* pc)
//{
//	assert(pc);
//
//
//	if (pc->sz == 1000)
//	{
//		printf("通讯录储存信息已满");
//		return;
//	}
//	else
//		printf("请输入名字:");
//	scanf("%s", &pc->data[pc->sz].name);
//	printf("请输入性别:");
//	scanf("%s", &pc->data[pc->sz].sex);
//	printf("请输入年龄:");
//	scanf("%d", &pc->data[pc->sz].age);
//	printf("请输入电话:");
//	scanf("%s", &pc->data[pc->sz].tele);
//	printf("请输入地址:");
//	scanf("%s", &pc->data[pc->sz].addr);
//
//	pc->sz++;
//	printf("通讯录增加成功!!!\n");
//}


//动态内存版本

void CheckCapacity(Contact* pc)
{
	assert(pc);
	if (pc->sz == pc->capacity)
	{
		PeoInfo* ptr = (PeoInfo*)realloc(pc->data, (pc->capacity + DEFAULE_INC) * sizeof(PeoInfo));
		if (ptr != NULL)
		{
			pc->data = ptr;
			pc->capacity += DEFAULE_INC;
			printf("增容成功!!\n");
		}
		else
		{
			perror("AddContact->realloc");
			return;
		}
	}
	
}


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

void AddContact(Contact* pc)
{
	assert(pc);


	CheckCapacity(pc);

	
	printf("请输入名字:");
	scanf("%s", &pc->data[pc->sz].name);
	printf("请输入性别:");
	scanf("%s", &pc->data[pc->sz].sex);
	printf("请输入年龄:");
	scanf("%d", &pc->data[pc->sz].age);
	printf("请输入电话:");
	scanf("%s", &pc->data[pc->sz].tele);
	printf("请输入地址:");
	scanf("%s", &pc->data[pc->sz].addr);

	pc->sz++;
	printf("通讯录增加成功!!!\n");
}



void ShowContact(const Contact* pc)
{
	assert(pc);

	if (pc->sz == 0)
	{
		printf("通讯录为空,无需打印");
		return;
	}

	printf("%-20s%-5s%-5s%-12s%-30s\n", "姓名", "年龄", "性别", "电话", "住址");

	for (int i = 0; i < pc->sz; i++)
	{
		printf("%-20s%-5d%-5s%-12s%-30s\n", pc->data[i].name,
			pc->data[i].age,
			pc->data[i].sex,
			pc->data[i].tele,
			pc->data[i].addr);
	}
}
int FindByName(Contact* pc, char name[])
{
	assert(pc);
	for (int i = 0; i < pc->sz; i++)
	{
		if (strcmp(pc->data[i].name, name) == 0)
		{
			return i;
		}
	}
	return -1;
}


void DelContact(Contact* pc)
{
	char name[NAME_MAX];
	assert(pc);
	if (pc->sz == 0)
	{
		printf("通讯录为空,无法删除\n");
		return;
	}


	printf("请输入被删除人的姓名:");
	scanf("%s", name);

	//查找是否存在

	int ret = FindByName(pc, name);
	if (ret == -1)

	{
		printf("要删除的人不存在\n");
		return;
	}
	//删除这个人
	int i = 0;
	for (i = ret; i < pc->sz - 1; i++)
	{
		pc->data[i] = pc->data[i + 1];

	}
	pc->sz--;
	printf("删除成功\n");

}

void SearchContact(Contact* pc)
{
	char name[NAME_MAX];
	assert(pc);
	printf("请输入查找的联系人姓名:");
	scanf("%s", name);

	//查找是否存在

	int ret = FindByName(pc, name);
	if (ret == -1)
	{
		printf("要查找的人不存在\n");
		return;
	}
	printf("%-20s%-5s%-5s%-12s%-30s\n", "姓名", "年龄", "性别", "电话", "住址");
	printf("%-20s%-5d%-5s%-12s%-30s\n", pc->data[ret].name,
		pc->data[ret].age,
		pc->data[ret].sex,
		pc->data[ret].tele,
		pc->data[ret].addr);

}

void ModifyContact(Contact* pc)
{

	char name[NAME_MAX];
	assert(pc);
	printf("请输入修改的联系人姓名:");
	scanf("%s", name);

	int ret = FindByName(pc, name);
	if (ret == -1)
	{
		printf("要修改的人不存在\n");
		return;
	}

	printf("请输入名字:");
	scanf("%s", &pc->data[ret].name);
	printf("请输入性别:");
	scanf("%s", &pc->data[ret].sex);
	printf("请输入年龄:");
	scanf("%d", &pc->data[ret].age);
	printf("请输入电话:");
	scanf("%s", &pc->data[ret].tele);
	printf("请输入地址:");
	scanf("%s", &pc->data[ret].addr);
	printf("修改成功!!\n");
}


void SortContact(Contact* pc)
{
	assert(pc);

	if (pc->sz == 0)
	{
		printf("通讯录为空,无需排序");
		return;
	}
	int i = 0;
	PeoInfo temp;
	for (i = 0; i < pc->sz - 1; i++)
	{

		for (int j = 0; j < pc->sz - i - 1; j++)
		{
			if ((strcmp(pc->data[j].name, pc->data[j + 1].name)) > 0)
			{
				temp = pc->data[j + 1];
				pc->data[j + 1] = pc->data[j];
				pc->data[j] = temp;
			}
		}

	}
	printf("排序成功!!!\n");
}

//主函数及菜单区域






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

enum Option           //枚举常量
{
	EXIT,
	ADD,
	DEL,
	SEARCH,
	MODIFY,
	SHOW,
	SORT
};

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);
			break;
		case SEARCH:                                          //查
			SearchContact(&con);
			break;
		case MODIFY:                                          //改
			ModifyContact(&con);
			break;
		case SHOW:                                            //显示
			ShowContact(&con);
			break;
		case SORT:                                            //排序
			SortContact(&con);
			break;
		case EXIT:                                            //退出
			DestroyContact(&con);                             //释放内存
			printf("退出通讯录\n");
			break;
		default:
			printf("选择错误,重新选择\n");
			break;
		};




	} while (input);
	return 0;
}

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值