模拟实现通讯录

1.通讯录

生活中我们肯定会用到通讯录的,通讯录中会存放了我们认识人的联系方式,姓名,家庭住址等等。
那么一个通讯录它最基础应该有那些功能呢?

  • 增加联系人的信息
  • 删除联系人的信息
  • 查找联系人的信息
  • 修改联系人的信息
  • 打印通讯录中所有人的信息
  • 按首字母对通讯录进行排序

了解完通讯录的功能我们先写这个无比熟悉的菜单。

//test.c
void menu()
{
	printf("******************************\n");
	printf("****1.ADD       2.DELE    ****\n");
	printf("****3.SEAR      4.REVI    ****\n");
	printf("****5.SHOW      6.SORT    ****\n");
	printf("****0.EXIT                ****\n");
	printf("******************************\n");
}
int main()
{
	int input = 0;
	do 
	{
		menu();//菜单
		printf("请选择:>");
		scanf("%d",&input);
		switch(input)
		{
			case 1:
				break;
			case 2:
				break;
			case 3:
				break;
			case 4:
				break;
			case 5:
				break;
			case 6:
				break;
			case 0:
				break;
			default:
				break;
		}
	}while(input);
	return 0;
}

1.1 定义结构体

先确定每个联系人都应该具备的信息

  • 姓名
  • 年龄
  • 性别
  • 电话
  • 地址
    了解完后,我们将这些信息都封装成一个结构体buddies
//contacts.h
struct buddies
{
	char name[20];//姓名
	int age;//年龄
	char sex[10];//性别
	char tel[16];//电话
	char add[30];//地址
};

封装完联系人的信息后,我们再封装通讯录,这个通讯录应该具有存储联系人的能力,以及记录当前联系人的数目。为了存储大量的联系人信息我们定义一个数组就可以了。

//contacts.h
struct Contacts
{
	struct buddies data[100];
	int size;
};

1.2 利用标识常量和枚举

在上面的代码中我们用到了很多的常量,为了方便后续的修改,我们可以利用#define来定义标识常量来替代这些数字常量。同时我们来利用typedef来简化代码

//contacts.h
#define MAX 100
#define MAX_NAME 20
#define MAX_SEX 10
#define MAX_TEL 16
#define MAX_ADD 30

typedef struct buddies
{
	char name[MAX_NAME];//姓名
	int age;//年龄
	char sex[MAX_SEX];//性别
	char tel[MAX_TEL];//电话
	char add[MAX_ADD];//地址
}buddies;

typedef struct contact
{
	buddies data[MAX];
	int size;
}contact;

枚举我们可以用来处理主函数中switch数字意义不明的问题,当别人看到你的源码时是分不清楚你写的那些数字是什么意思的,为此我们就要利用枚举来帮助我们了。

//contacts.h
enum select
{
	EXIT,
	ADD,
	DELE,
	SEAR,
	REVI,
	SHOW,
	SORT
};
//test.c
void menu()
{
	printf("******************************\n");
	printf("****1.ADD       2.DELE    ****\n");
	printf("****3.SEAR      4.REVI    ****\n");
	printf("****5.SHOW      6.SORT    ****\n");
	printf("****0.EXIT                ****\n");
	printf("******************************\n");
}
int main()
{
	int input = 0;
	do 
	{
		menu();//菜单
		printf("请选择:>");
		scanf("%d",&input);
		switch(input)
		{
			case ADD:
				break;
			case DELE:
				break;
			case SEAR:
				break;
			case REVI:
				break;
			case SHOW:
				break;
			case SORT:
				break;
			case EXIT:
				break;
			default:
				break;
		}
	}while(input);
	return 0;
}

2.实现通讯录

2.1 通讯录的初始化

完成什么的准备后,我们就要开始为通讯录赋初值了,也就是通讯录的初始化。在初始化中我们要将size初始化为0,data也初始化为0.

void InitContact(contact* pc)
{
	memset(pc->data,0,sizeof(pc->data));
	pc->size = 0;
}

2.2 增加联系人

功能:输入要添加的联系人信息

增加联系人,在增加之前要先判断一下通讯录是不是已经存满了,如果存满了就直接退出。
每存满才能在通讯录中添加数据。

void AddContact(contact* pc)
{
	if (pc->size > MAX)
	{
		printf("通讯录已满\n");
		return;
	}
	printf("请输入姓名:>");
	scanf("%s", pc->data[pc->size].name);
	printf("请输入年龄:>");
	scanf("%d", &pc->data[pc->size].age);
	printf("请输入性别:>");
	scanf("%s", pc->data[pc->size].sex);
	printf("请输入电话:>");
	scanf("%s", pc->data[pc->size].tel);
	printf("请输入地址:>");
	scanf("%s", pc->data[pc->size].add);
	printf("联系人添加完成\n");
	//添加成功,size要加1
	pc->size += 1;
}

2.2 删除联系人

功能:先根据用户输入的姓名信息查找出联系人,然后在删除该联系人。

删除指定联系人,联系人那么多信息,这里我们利用的联系人姓名来筛选删除的对象。现在中是会用重名的可能,但是这里不考虑这方面,当然大家可以也利用联系人的电话来查找要删除的对象,电话比较唯一,就是难记忆了。
当然如果通讯录为空就没必要删除了。

void DeleteContact(contact* pc)
{
	//通讯录为空,就退出
	if(pc->size == 0)
	{
		printf("通讯录为空\n");
		return;
	}
	//查找要删除的联系人
	int pos = 0;
	int flag = 0;
	char tmp[MAX_NAME] = {0};
	scanf("%s",tmp);
	for(int i = 0;i<pc->size;++i)
	{
		if(strcmp(tmp,pc->data[i].name)==0)
		{
			pos = i;
			flag = 1;
		}
	}
	if(flag==0)
	{
		printf("没找到\n");
		return;
	}
	//因为有一个数据要被删除,当它被删除时,其后面的数据需要挪动到前面一格。
	for(int i = pos;i<pc->size-1;++i)
	{
		pc->data[i] = pc->data[i+1];//后面数据往前覆盖
	}
	printf("删除联系人成功\n");
	pc->size-=1;
}

上面的代码可以优化,在查找联系人那里,我们可以将其封装成一个函数,因为在后续的代码中,比如修改联系人信息,也是需要先查找联系人的。还要后面打打印指定联系人也是需要先查找联系人。所以呢将查找联系人封装成一个函数可以便利后续的代码书写。

//找到返回下标,没找到返回-1
int FindCon(contact* pc)
{
	char tmp[MAX_NAME] = { 0 };
	printf("请输入姓名:>");
	scanf("%s", tmp);
	for (int i = 0; i < pc->size; ++i)
	{
		if (strcmp(tmp, pc->data[i].name) == 0)
		{
			return i;
		}
	}
	return -1;
}
void DeleteContact(contact* pc)
{
	//通讯录为空,就退出
	if(pc->size == 0)
	{
		printf("通讯录为空\n");
		return;
	}
	//查找要删除的联系人
	int pos = FindCon(pc);
	if(pos == -1)
	{
		printf("找不到\n");
		return;
	}
	//因为有一个数据要被删除,当它被删除时,其后面的数据需要挪动到前面一格。
	for(int i = pos;i<pc->size-1;++i)
	{
		pc->data[i] = pc->data[i+1];//后面数据往前覆盖
	}
	printf("删除联系人成功\n");
	pc->size-=1;
}

2.3 查找联系人

功能:是根据用户提供的联系人姓名,然后在屏幕打印出该联系人的全部信息

void SearchContact(contact* pc)
{
	//通讯录为空,就退出
	if(pc->size == 0)
	{
		printf("通讯录为空\n");
		return;
	}
	//查找要打印的联系人
	int pos = FindCon(pc);
	if(pos == -1)
	{
		printf("找不到\n");
		return;
	}
	printf("%-10s\t%-5s\t%-6s\t%-16s\t%-20s\n","姓名","年龄","性别","电话","地址");
	printf("%-10s\t%-5d\t%-6s\t%-16s\t%-20s\n",pc->data[pos].name,
								            pc->data[pos].age,
								            pc->data[pos].sex,
								            pc->data[pos].tel,
								            pc->data[pos].add);
	
}

2.4 修改联系人信息

功能:先根据用户输入的姓名信息查找出联系人,然后在修改该联系人的信息。

和删除指定联系人的步骤差不多,不过当前函数的主要目的是修改。
当前函数我们要实现的修改是该联系人的全部信息都修改。

void ReviseContact(contact* pc)
{
	//通讯录为空,就退出
	if(pc->size == 0)
	{
		printf("通讯录为空\n");
		return;
	}
	//查找要修改的联系人
	int pos = FindCon(pc);
	if(pos == -1)
	{
		printf("找不到\n");
		return;
	}
	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].tel);
	printf("请输入地址:>");
	scanf("%s",pc->data[pos].add);
	printf("联系人修改完成\n");
}

2.5 显示全部联系人信息

功能:将通讯录的所有联系人的信息都打印出来。

void ShowContact(contact* pc)
{
	printf("%-10s\t%-5s\t%-6s\t%-16s\t%-20s\n","姓名","年龄","性别","电话","地址");
	for(int i = 0;i<pc->size;++i)
	{
		printf("%-10s\t%-5d\t%-6s\t%-16s\t%-20s\n",pc->data[i].name,
								            pc->data[i].age,
								            pc->data[i].sex,
								            pc->data[i].tel,
								            pc->data[i].add);
	}
}

2.6 对通讯录进行排序

功能:将姓名ASCII码靠前的联系人排在前面。

利用C语言的库函数qsort来排序。

int cmp_contact(void* p1, void* p2)
{
	return strcmp(((buddies*)p1)->name, ((buddies*)p2)->name);
}
void SortContact(contact* pc)
{
	qsort(pc->data, pc->size, sizeof(buddies), cmp_contact);
	ShowContact(pc);
}

3.代码整合

//contact.h
#include <stdio.h>
#include <assert.h>
#include <string.h>

#define MAX 100
#define MAX_NAME 20
#define MAX_SEX 10
#define MAX_TEL 16
#define MAX_ADD 30

enum select
{
	EXIT,
	ADD,
	DELE,
	SEAR,
	REVI,
	SHOW,
	SORT
};

typedef struct buddies
{
	char name[MAX_NAME];//姓名
	int age;//年龄
	char sex[MAX_SEX];//性别
	char tel[MAX_TEL];//电话
	char add[MAX_ADD];//地址
}buddies;

typedef struct contact
{
	buddies data[MAX];
	int size;
}contact;

void InitContact(contact* pc);

void AddContact(contact* pc);

void DeleteContact(contact* pc);

void SearchContact(contact* pc);

void ReviseContact(contact* pc);

void ShowContact(contact* pc);

void SortContact(contact* pc);

//contact.c
#include "contact.h"

void InitContact(contact* pc)
{
	memset(pc->data, 0, sizeof(pc->data));
	pc->size = 0;
}

void AddContact(contact* pc)
{
	if (pc->size > MAX)
	{
		printf("通讯录已满\n");
		return;
	}
	printf("请输入姓名:>");
	scanf("%s", pc->data[pc->size].name);
	printf("请输入年龄:>");
	scanf("%d", &pc->data[pc->size].age);
	printf("请输入性别:>");
	scanf("%s", pc->data[pc->size].sex);
	printf("请输入电话:>");
	scanf("%s", pc->data[pc->size].tel);
	printf("请输入地址:>");
	scanf("%s", pc->data[pc->size].add);
	printf("联系人添加完成\n");
	//添加成功,size要加1
	pc->size += 1;
}

//找到返回下标,没找到返回-1
int FindCon(contact* pc)
{
	char tmp[MAX_NAME] = { 0 };
	printf("请输入姓名:>");
	scanf("%s", tmp);
	for (int i = 0; i < pc->size; ++i)
	{
		if (strcmp(tmp, pc->data[i].name) == 0)
		{
			return i;
		}
	}
	return -1;
}
void DeleteContact(contact* pc)
{
	//通讯录为空,就退出
	if (pc->size == 0)
	{
		printf("通讯录为空\n");
		return;
	}
	//查找要删除的联系人
	int pos = FindCon(pc);
	if (pos == -1)
	{
		printf("找不到\n");
		return;
	}
	//因为有一个数据要被删除,当它被删除时,其后面的数据需要挪动到前面一格。
	for (int i = pos; i < pc->size - 1; ++i)
	{
		pc->data[i] = pc->data[i + 1];//后面数据往前覆盖
	}
	printf("删除联系人成功\n");
	pc->size -= 1;
}

void SearchContact(contact* pc)
{
	//通讯录为空,就退出
	if (pc->size == 0)
	{
		printf("通讯录为空\n");
		return;
	}
	//查找要打印的联系人
	int pos = FindCon(pc);
	if (pos == -1)
	{
		printf("找不到\n");
		return;
	}
	printf("%-10s\t%-5s\t%-6s\t%-16s\t%-20s\n", "姓名", "年龄", "性别", "电话", "地址");
	printf("%-10s\t%-5d\t%-6s\t%-16s\t%-20s\n", pc->data[pos].name,
		pc->data[pos].age,
		pc->data[pos].sex,
		pc->data[pos].tel,
		pc->data[pos].add);

}

void ReviseContact(contact* pc)
{
	//通讯录为空,就退出
	if (pc->size == 0)
	{
		printf("通讯录为空\n");
		return;
	}
	//查找要修改的联系人
	int pos = FindCon(pc);
	if (pos == -1)
	{
		printf("找不到\n");
		return;
	}
	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].tel);
	printf("请输入地址:>");
	scanf("%s", pc->data[pos].add);
	printf("联系人修改完成\n");
}

void ShowContact(contact* pc)
{
	printf("%-10s\t%-5s\t%-6s\t%-16s\t%-20s\n", "姓名", "年龄", "性别", "电话", "地址");
	for (int i = 0; i < pc->size; ++i)
	{
		printf("%-10s\t%-5d\t%-6s\t%-16s\t%-20s\n", pc->data[i].name,
			pc->data[i].age,
			pc->data[i].sex,
			pc->data[i].tel,
			pc->data[i].add);
	}
}

int cmp_contact(void* p1, void* p2)
{
	return strcmp(((buddies*)p1)->name, ((buddies*)p2)->name);
}
void SortContact(contact* pc)
{
	qsort(pc->data, pc->size, sizeof(buddies), cmp_contact);
	ShowContact(pc);
}

//test.c
#include "contact.h"

void menu()
{
	printf("******************************\n");
	printf("****1.ADD       2.DELE    ****\n");
	printf("****3.SEAR      4.REVI    ****\n");
	printf("****5.SHOW      6.SORT    ****\n");
	printf("****0.EXIT                ****\n");
	printf("******************************\n");
}
int main()
{
	int input = 0;
	contact ct;
	InitContact(&ct);
	do
	{
		menu();//菜单
		printf("请选择:>");
		scanf("%d", &input);
		switch (input)
		{
		case ADD:
			AddContact(&ct);
			break;
		case DELE:
			DeleteContact(&ct);
			break;
		case SEAR:
			SearchContact(&ct);
			break;
		case REVI:
			ReviseContact(&ct);
			break;
		case SHOW:
			ShowContact(&ct);
			break;
		case SORT:
			SortContact(&ct);
			break;
		case EXIT:
			printf("退出程序\n");
			break;
		default:
			printf("请重新输入\n");
			break;
		}
	} while (input);
	return 0;
}

当前面代码与代码整合冲突时,以代码整合中的为准。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Yui_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值