通讯录的实现(增删查改排序)

本课题模拟通讯录的实现,包括:

1.增加联系人的信息

2.删除联系人

3.查找联系人

4.修改联系人信息

5.对联系人进行排序

本节目录:

通讯录的实现样貌展示:这就算通讯录的菜单

下面对每个功能进行模块性讲解。

一、通讯录变量的创建

【思路1】

    通讯录是一个复杂的对象,包含了用户的名字、性别、年龄、电话号码和家庭住址等信息,所以需要用结构体来定义

#define NAME_MAX 20
#define SEX_MAX 6
#define TELE_MAX 20
#define ADDR_MAX 20
typedef struct PeoInfo
{
	char name[NAME_MAX];//姓名
	char sex[SEX_MAX];//性别
	int age;//年龄
	char tele[TELE_MAX];//电话
	char addr[ADDR_MAX];//地址
}PeoInfo;

为了方便后续修改结构体中每个成员的大小范围,使用了宏定义的常量,来表示每个数组的大小。

【思路2】

(1)这是一个结构体类型,用来创造变量,一次只能创建一个,不合适,所以需要数组。

(2)因为通讯录是数组,所以需要一个变量来实时记录通讯录的个数。

(3)为了可以使用,他们需要同类型,所以还需要再创造一个结构体

#define MAX 100
typedef struct contact
{
	PeoInfo data[MAX];//通讯录
	int sz;//记录通讯录的个数
}contact;

接下来再用contact创造变量就好 

contact con;//通讯录变量的创建

二、通讯录的初始化

(1)需要修改通讯录中的内容,需要传结构体的地址

InitContact(&con);//传参

(2)初始化函数

void InitContact(contact* pc)
{
	assert(pc);
	memset(pc->data,0,sizeof(pc->data));
	pc->sz = 0;//通讯录开始的容量为0
}

(1)用assert函数判断指针是否为空,为空则会退出程序。需要包含头文件:#include<assert.h>

(2)用memset函数将通讯录中的内容设置成0即可。需要包含头文件:#include<string.h>

三、通讯录信息的添加(add)

(1)信息添加的条件

在信息添加前我们需要查看通讯录是否已满,满了则不能再继续添加信息。

传参:

AddContact(&con);

通讯录判满:

void AddContact(contact* pc)
{
    assert(pc);//指针判空操作
    if (pc->sz == MAX)
	{
		printf("通讯录已满,存入信息失败\n");
		return;
	}
}

(2)信息添加的过程

void AddContact(contact* pc)
{
	assert(pc);	
		if (pc->sz == MAX)
		{
			printf("通讯录已满,存入信息失败\n");
			return;
		}
		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");
}

(1)逐一对通讯录进行信息添加即可,需要注意结构体的访问方式

(2)data数组的第一个联系人的下标是0,等于sz的值

(3)信息添加的完善

以上的操作每次只能添加一个人的信息,很不方便。所以我们使用go语句循环以上的代码

void AddContact(contact* pc)
{
	assert(pc);
	int adds;
		back://go语句标记2
		if (pc->sz == MAX)
		{
			printf("通讯录已满,存入信息失败\n");
			return;
		}
		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");
        //循环是否继续的判断
		printf("是否继续添加联系人信息1/0:");
		scanf("%d",&adds);
		if (adds == 1)
			goto back;//go语句标记1
		else
		{
			return;
		}
}

四、通讯录的打印(show)

当已经可以想通讯录中添加了联系人信息之后,就可以将他们的信息打印在屏幕上进行验证:

(1)可以打印通讯录的条件

传参:

ShowContact(&con);

通讯录判空:

void ShowContact(contact* pc)
{
	assert(pc);
	if (pc->sz == 0)
	{
		printf("通讯录为空\n");
		return;
	}
}

如果通讯录一个信息都没有,将不会打印

(2)通讯录的打印

void ShowContact(contact* pc)
{
	assert(pc);
	if (pc->sz == 0)
	{
		printf("通讯录为空\n");
		return;
	}
	printf("%-10s %-5s %-10s %-15s %-10s\n","名字","性别","年龄","电话","住址");
	int i = 0;
	for (i=0;i<pc->sz;i++)
	{
		printf("%-10s %-5s %-10d %-15s %-10s\n",
			pc->data[i].name, pc->data[i].sex, pc->data[i].age,
			pc->data[i].tele, pc->data[i].addr);
	}
	printf("\n");
}

(1)通讯录打印的时候,注意打印的格式

(2)%-10s:实现的是左对齐

五、删除联系人(del)

(1)通讯录的判空

传参:

DelContact(&con);

判空:

void DelContact(contact* pc)
{
	assert(pc);
	if (pc->sz == 0)
	{
		printf("通讯录为空,删除失败\n");
		return;
	}
}

(2)删除联系人的条件

 如果需要删除的联系人不存在,那么也将会删除失败。所以需要查找联系人是否存在

查找函数:(联系人存在,返回联系人的下标;不存在返回-1)

传参:

    printf("请输入你要删除的联系人:");
	char name[NAME_MAX];
	scanf("%s",name);
	int ret = FindContact(pc,name);
static int FindContact(contact* pc,char name[])
{
	assert(pc);
	int i = 0;
	for (i=0;i<pc->sz;i++)
	{
		if (strcmp(name, pc->data[i].name) == 0)
			return i;
	}
	return -1;
}

(3)删除操作

void DelContact(contact* pc)
{
	assert(pc);
	if (pc->sz == 0)
	{
		printf("通讯录为空,删除失败\n");
		return;
	}
	printf("请输入你要删除的联系人:");
	char name[NAME_MAX];
	scanf("%s",name);
	int ret = FindContact(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");
}

六、查找联系人并打印(Search)

依然需要用到上述的查找某位联系人是否存在的函数

传参:

SearchContact(&con);

(1)先查找

void SearchContact(contact* pc)
{
	assert(pc);
	printf("请输入你要查找联系人的名字:");
	char name[NAME_MAX];
	scanf("%s", name);
	int ret = FindContact(pc, name);
}

(2)后打印

联系人存在就打印该联系人的信息

void SearchContact(contact* pc)
{
	assert(pc);
	printf("请输入你要查找联系人的名字:");
	char name[NAME_MAX];
	scanf("%s", name);
	int ret = FindContact(pc, name);
	if (ret == -1)
	{
		printf("联系人不存在,查找失败\n");
		return;
	}
	printf("查找成功:\n");
	printf("%-10s %-5s %-10s %-15s %-10s\n", "名字", "性别", "年龄", "电话", "住址");
	printf("%-10s %-5s %-10d %-15s %-10s\n",
		pc->data[ret].name, pc->data[ret].sex, pc->data[ret].age,
		pc->data[ret].tele, pc->data[ret].addr);
}

七、修改联系人(modify)

想要修改某位联系人的信息,首先确定该联系人是否存在

传参:

ModifyContact(&con);

(1)查找联系人

void ModifyContact(contact* pc)
{
	assert(pc);
	printf("请输入你要查找联系人的名字:");
	char name[NAME_MAX];
	scanf("%s", name);
	int ret = FindContact(pc, name);
	if (ret == -1)
	{
		printf("联系人不存在,修改失败\n");
		return;
	}
}

(2)修改联系人信息

void ModifyContact(contact* pc)
{
	assert(pc);
	printf("请输入你要查找联系人的名字:");
	char name[NAME_MAX];
	scanf("%s", name);
	int ret = FindContact(pc, name);
	if (ret == -1)
	{
		printf("联系人不存在,修改失败\n");
		return;
	}
	printf("联系人存在:");
	printf("%-10s %-5s %-10d %-15s %-10s\n",
	pc->data[ret].name, pc->data[ret].sex, pc->data[ret].age,
	pc->data[ret].tele, pc->data[ret].addr);
	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修改成功");
}

八、联系人排序

对联系人排序,使用库函数中的排序函数qsort,我们只需要完成比较函数即可。

排序可以按照名字的字典顺序或者年龄等,我们这里介绍名字和年龄的排序。

(1)按照名字排序

传参:

qsort(pc->data, pc->sz, sizeof(pc->data[0]), qsort_cmp_name);

第四个为函数指针,指向的比较函数需要我们自己完成

名字的比较函数:

//名字排序
int qsort_cmp_name(const void* e1,const void* e2)
{
	return strcmp((((contact*)e1)->data)->name, (((contact*)e2)->data)->name);
}

(1) 名字的字典顺序,其实就算字符串的比较。

(2)字符串比较需要用函数strcmp,头文件#include<string.h>

(2)按照年龄排序

传参:

qsort(pc->data, pc->sz, sizeof(pc->data[0]), qsort_cmp_age);

年龄的比较函数:

//年龄排序
int qsort_cmp_age(const void* e1,const void* e2)
{
	return (((contact*)e1)->data)->age - (((contact*)e2)->data)->age;
}

(3)完整排序函数

void menu2()
{
	printf("*************************\n");
	printf("**** 1.名字   2.年龄 ****\n");
	printf("*************************\n");
}
//联系人排序
void SortContact(contact* pc)
{
	int input2;
	menu2();
	printf("请选择排序方式:");
	scanf("%d",&input2);
	switch (input2)
	{
	case 1:qsort(pc->data, pc->sz, sizeof(pc->data[0]), qsort_cmp_name);break;
	case 2:qsort(pc->data, pc->sz, sizeof(pc->data[0]), qsort_cmp_age);break;
	defualt:printf("选择错误\n");
		break;
	}
}

每进入一次该函数,只能排序一次,不需要设置循环

九、菜单的实现

(1)主函数部分

enum Option
{
	EXIT,//退出
ADD,//增加
DEL,//删除联系人
SEARCH,//查找联系人
MODIFY,//修改指定联系人
SHOW,//打印联系人
SORT,//分类
};
int main()
{
    contact con;
	InitContact(&con);
	int input;
	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;
}

【代码思路】

(1)do…while循环配合switch选择语句完成菜单的构造。可以供用户多次选择,直至退出

(2)在选择语句中

(2)菜单函数

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

所谓的菜单,就算打印出来让我们看。具体的选项还是得由主函数部分实现。

十、完整通讯录代码

#define _CRT_SECURE_NO_WARNINGS 1

#include<stdio.h>
#include<string.h>
#include<assert.h>
#include<stdlib.h>

#define NAME_MAX 20
#define SEX_MAX 6
#define TELE_MAX 20
#define ADDR_MAX 20

#define MAX 100

typedef struct PeoInfo
{
	char name[NAME_MAX];//姓名
	char sex[SEX_MAX];//性别
	int age;//年龄
	char tele[TELE_MAX];//电话
	char addr[ADDR_MAX];//地址
}PeoInfo;

typedef struct contact
{
	PeoInfo data[MAX];//通讯录
	int sz;//记录通讯录的个数
}contact;

//函数的声明
//初始化
 void InitContact(contact* pc);

 //添加用户信息
 void AddContact(contact* pc);

 //打印通讯录
 void ShowContact(contact* pc);

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

 //查找某个联系人
 void SearchContact(contact* pc);

 //修改联系人
 void ModifyContact(contact* pc);

 //联系人排序
 void SortContact(contact* pc);

//函数功能的实现

void InitContact(contact* pc)
{
	assert(pc);
	memset(pc->data,0,sizeof(pc->data));
	pc->sz = 0;
}
void ShowContact(contact* pc)
{
	assert(pc);
	if (pc->sz == 0)
	{
		printf("通讯录为空\n");
		return;
	}
	printf("%-10s %-5s %-10s %-15s %-10s\n","名字","性别","年龄","电话","住址");
	int i = 0;
	for (i=0;i<pc->sz;i++)
	{
		printf("%-10s %-5s %-10d %-15s %-10s\n",
			pc->data[i].name, pc->data[i].sex, pc->data[i].age,
			pc->data[i].tele, pc->data[i].addr);
	}
	printf("\n");
}

void AddContact(contact* pc)
{
	assert(pc);
	int adds;
		back:
		if (pc->sz == MAX)
		{
			printf("通讯录已满,存入信息失败\n");
			return;
		}

		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");

		printf("是否继续添加联系人信息1/0:");
		scanf("%d",&adds);
		if (adds == 1)
			goto back;
		else
		{
			return;
		}
}
//查看某个联系人是否存在
static int FindContact(contact* pc,char name[])
{
	assert(pc);
	int i = 0;
	for (i=0;i<pc->sz;i++)
	{
		if (strcmp(name, pc->data[i].name) == 0)
			return i;
	}
	return -1;
}
//删除联系人
void DelContact(contact* pc)
{
	assert(pc);
	if (pc->sz == 0)
	{
		printf("通讯录为空,删除失败\n");
		return;
	}
	printf("请输入你要删除的联系人:");
	char name[NAME_MAX];
	scanf("%s",name);
	int ret = FindContact(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)
{
	assert(pc);
	printf("请输入你要查找联系人的名字:");
		char name[NAME_MAX];
	scanf("%s", name);
	int ret = FindContact(pc, name);
	if (ret == -1)
	{
		printf("联系人不存在,查找失败\n");
		return;
	}
	printf("查找成功:\n");
	printf("%-10s %-5s %-10s %-15s %-10s\n", "名字", "性别", "年龄", "电话", "住址");
	printf("%-10s %-5s %-10d %-15s %-10s\n",
		pc->data[ret].name, pc->data[ret].sex, pc->data[ret].age,
		pc->data[ret].tele, pc->data[ret].addr);
}
//修改联系人
void ModifyContact(contact* pc)
{
	assert(pc);
	printf("请输入你要查找联系人的名字:");
	char name[NAME_MAX];
	scanf("%s", name);
	int ret = FindContact(pc, name);
	if (ret == -1)
	{
		printf("联系人不存在,修改失败\n");
		return;
	}
	printf("联系人存在:");
	printf("%-10s %-5s %-10d %-15s %-10s\n",
		pc->data[ret].name, pc->data[ret].sex, pc->data[ret].age,
		pc->data[ret].tele, pc->data[ret].addr);
	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 menu2()
{
	printf("*************************\n");
	printf("**** 1.名字   2.年龄 ****\n");
	printf("*************************\n");

}
//名字排序
int qsort_cmp_name(const void* e1,const void* e2)
{
	return strcmp((((contact*)e1)->data)->name, (((contact*)e2)->data)->name);
}
//年龄排序
int qsort_cmp_age(const void* e1,const void* e2)
{
	return (((contact*)e1)->data)->age - (((contact*)e2)->data)->age;
}
//联系人排序
void SortContact(contact* pc)
{
	int input2;
	menu2();
	printf("请选择排序方式:");
	scanf("%d",&input2);
	switch (input2)
	{
	case 1:qsort(pc->data, pc->sz, sizeof(pc->data[0]), qsort_cmp_name);break;
	case 2:qsort(pc->data, pc->sz, sizeof(pc->data[0]), qsort_cmp_age);break;
	defualt:printf("选择错误\n");
		break;
	}
}

//主函数及菜单
void menu()
{
	printf("********************************\n");
	printf("**** 1. add      2. del     ****\n");	
	printf("**** 3. search   4. modify  ****\n");
	printf("**** 5. show     6. sort    ****\n");
	printf("**** 0. exit                ****\n");
	printf("********************************\n");
}
enum Option
{
EXIT,//退出
ADD,//增加
DEL,//删除联系人
SEARCH,//查找联系人
MODIFY,//修改指定联系人
SHOW,//打印联系人
SORT,//分类
};
int main()
{
	contact con;
	InitContact(&con);
	int input;
	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;
}

至此,通讯录的实现完成。


  • 14
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 8
    评论
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

代码小娥

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

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

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

打赏作者

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

抵扣说明:

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

余额充值