前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【通讯录项目 (3 / 3)】基于顺序表的通讯录实现——通讯录项目实现

【通讯录项目 (3 / 3)】基于顺序表的通讯录实现——通讯录项目实现

作者头像
叫我龙翔
发布2024-01-30 13:57:38
1250
发布2024-01-30 13:57:38
举报
文章被收录于专栏:就业 C++ 综合学习

【通讯录项目 (3 / 3)】基于顺序表的通讯录实现——通讯录项目实现

前言

前两章我们已经知道顺序表的功能并完成了功能实现,下面我们将实现通讯录的以下功能:

在这里插入图片描述
在这里插入图片描述

1 项目预备工作

1.1 多文件处理

首先我们要对所用文件进行分类管理,以便后续操作。

在这里插入图片描述
在这里插入图片描述

我们将要在顺序表的基础上增加“contact.h”头文件和“contact.c”功能文件 注意头文件的正确引用 如下

在这里插入图片描述
在这里插入图片描述

请仔细检查,这是完成较大项目的基础。不同文件管理不同内容,方便快捷,效率高。

1.2 联系人数据管理

接下来是联系人的数据管理,我们需要改变原本顺序表的“SLDataType”为一个新类型。*我们可以想到联系人的信息不一,所以我们使用结构体来管理数据。

代码语言:javascript
复制
#define NAME_MAX 100
#define SEX_MAX 4
#define TEL_MAX 20
#define ADDR_MAX 200

//前置声明
typedef struct SeqList  contact;

//用户数据
typedef struct PersonInfo
{
	char name[NAME_MAX];
	char sex[SEX_MAX];
	int age;
	char tel[TEL_MAX];
	char addr[ADDR_MAX];
}PeoInfo;

我们用宏定义常量,方便后续查看修改。这里我设置了姓名 性别 年龄 号码 地址五种信息。代码中“前置声明”是为了避免后续引用出现问题。我们通过“typedef”进行重命名,方便后续书写代码。

2 功能实现

上面将我们的准备工作进行完毕,下面开始实现功能。我们基于顺序表在进行操作。如有不理解的地方请参考【通讯录项目 (2 / 3)】,下面不对 顺序表功能 进行详细说明 我们会使用顺序表大多数功能,请理解顺序表的功能在进行阅读。

2.1 初始化通讯录

“初始化”只需要简单的引用顺序表的初始化即可。

代码语言:javascript
复制
void InitContact(contact* con)
{
	SLInit(con);
}
代码语言:javascript
复制
void SLInit(SL* ps)
{
	assert(ps);//断言判断是否为空
	ps->a = NULL;//将初始地址改为空
	ps->size = ps->capacity = 0;//容量与大小定为空
}

这样就实现了初始化,与初始化顺序表一致。

2.2 添加联系人

添加联系人也非常简单,只需要依次输入数据,在进行顺序表的插入即可。

代码语言:javascript
复制
void AddContact(contact* con)
{
	assert(con);
	PeoInfo info;
	printf("请输入联系人姓名:\n");
	scanf("%s", info.name);
	printf("请输入联系人的性别:\n");
	scanf("%s", info.sex);
	printf("请输入联系人的年龄:\n");
	scanf("%d", &info.age); //这里需要取地址,因为age是int类型,其余为数组
	printf("请输入联系人的电话:\n");
	scanf("%s", info.tel);
	printf("请输入联系人的住址:\n");
	scanf("%s", info.addr);

	SLPushBack(con,info);
	printf("添加成功\n");
	
}
代码语言:javascript
复制
void SLPushBack(SL* ps, SLDataType x)
{
	assert(ps);
	SLCheckCapacity(ps);
	ps->a[ps->size++] = x;
	
}

这样就进行了数据的加入。

2.3 删除联系人

删除联系人依然使用顺序表的删除功能。这里需要一个"查找联系人"的功能。需要通过一个信息来查找联系人是否存在。

2.3.1 查找目标

我们输入一个信息,来进行遍历查找联系人。返回目标的偏移值。

代码语言:javascript
复制
//查找联系人
int findname(contact* con, char name[NAME_MAX])
{
	assert(con);
	for (int i = 0; i < con->size; i++)
	{
		if (strcmp(con->a[i].name, name) == 0)
		{
			return i;
		}		
	}
	return -1;
}
2.3.2 删除联系人

同样使用顺序表的删除功能来实现,通过“查找联系人”返回的偏移值来进行定位

代码语言:javascript
复制
void DelContact(contact* con) 
{
	assert(con);
	char find[NAME_MAX] = { 0 };
	printf("请输入你想删除的联系人姓名:> \n");
	scanf("%s",find);
	int ret = findname(con, find);
	if (ret < 0)
	{
		printf("未找到该联系人\n");
	}
	else
		SLErase(con, ret);
}
代码语言:javascript
复制
void SLErase(SL*ps,int pos)
{                                                                                          
	assert(ps);
	if (pos >= 0 && pos < ps->size)
	{
		for (int i = pos; i < ps->size - 1; i++)
		{
			ps->a[i] = ps->a[i + 1];//a[size-2]=a[size-1]模拟最后一次查找
		}
		ps->size--;
	}
	else
		assert(pos);
}

这样通过覆盖就完成了删除功能。

2.4 展示通讯录

展示通讯录的功能是对顺序表展示的扩展。

代码语言:javascript
复制
void ShowContact(contact* pcon) {
	//打印通讯录所有的数据
	//先打印表头文字
	assert(pcon);
	printf("%s %s %s %s %s\n", "姓名", "性别", "年龄", "电话", "住址");
	for (int i = 0; i < pcon->size; i++)
	{
		printf("%-4s %-4s %-4d %-11s %-4s\n",
			pcon->a[i].name,
			pcon->a[i].sex,
			pcon->a[i].age,
			pcon->a[i].tel,
			pcon->a[i].addr
		);
	}
}

只需遍历顺序表,并打印联系人数据即可。 注意换行符,与打印格式让界面更加美观。

2.5 查找与修改

查找与修改操作相似,我们放在一起说明

2.5.1 查找联系人

查找联系人以上面的查找目标功能为基础,通过遍历进行查找。这里需要进行一次打印操作来展示查找结果

代码语言:javascript
复制
void FindContact(contact* con)
{
	assert(con);
	char find[NAME_MAX] = { 0 };
	printf("请输入想要查找的联系人姓名:> \n");
	scanf("%s",find);
	int ret = findname(con, find);
	if (ret < 0)
	{
		printf("未找到该联系人\n");
		
	}
	else{
		printf("找到了\n");
	printf("%s %s %s %s %s\n", "姓名", "性别", "年龄", "电话", "住址");
		printf("%-4s %-4s %-4d %-4s %-4s\n",
			con->a[ret].name,
			con->a[ret].sex,
			con->a[ret].age,
			con->a[ret].tel,
			con->a[ret].addr
		);
	}
}
2.5.2 修改联系人

修改联系人同样基于“查找目标”功能的基础,并进行一次修改操作。

代码语言:javascript
复制
oid ModifyContact(contact* con)
{
	assert(con);
	int name[NAME_MAX] = { 0 };
	printf("请输入想修改的联系人: > \n");
	scanf("%s", name);
	int ret = findname(con, name);
	//通过偏移量进行修改
	printf("请输入联系人姓名:\n");
	scanf("%s", con->a[ret].name);
	printf("请输入联系人的性别:\n");
	scanf("%s", con->a[ret].sex);
	printf("请输入联系人的年龄:\n");
	scanf("%d", &con->a[ret].age);
	printf("请输入联系人的电话:\n");
	scanf("%s", con->a[ret].tel);
	printf("请输入联系人的住址:\n");
	scanf("%s", con->a[ret].addr);
	printf("修改完成\n");
	ShowContact(con);

}
2.6 销毁通讯录

销毁功能是对储存空间的操作,通过free来实现销毁。

代码语言:javascript
复制
void DestroyContact(contact* con)
{
	assert(con);
	free(con->a);
	con->size = con->capacity = 0;
	con->a = NULL;
}

3 界面完成

上面我们已经实现了通讯录的大部分功能,还有一些额外功能没有加入,比如读取文件数据,储存到文件等。 下面我们开始完善界面内容,来把通讯录的功能进行整合。

3.1 打印菜单

这个容易实现,按照喜好设置即可,下面给予参考

代码语言:javascript
复制
void menu()
{
	printf("*************************************\n");
	printf("*********      通讯录      **********\n");
	printf("**** 1.添加联系人  2.删除联系人 *****\n");
	printf("**** 3.修改联系人  4.查找联系人 *****\n");
	printf("**** 5.查看通讯录  0.退出通讯录 *****\n");
}

效果如图

在这里插入图片描述
在这里插入图片描述
3.2 完成功能选择

通过switch语句我们可以方便的完成功能选择

代码语言:javascript
复制
int main()
{
	int op = -1;
	contact con;
	InitContact(&con);
	do {
		menu();
		printf("请选择你的操作:> \n");
		scanf("%d",&op);
		switch (op)
		{
			case 1:
				AddContact(&con);
				break;
			case 2:
				DelContact(&con);
				break;
			case 3:
				ModifyContact(&con);
				break;
			case 4:
				FindContact(&con);
				break;
			case 5:
				ShowContact(&con);
				break;
			case 0:
				printf("goodbye~\n");
				break;
			default:
				printf("输入格式有误,重新输入:> \n");
				break;
		}
	} while (op != 0);

	DestroyContact(&con);

	return 0;
}

这样我们就完成了功能选择,都是有一点点瑕疵。

3.3 界面优化

通过上面的菜单我们在进行几步操作后便会发现

在这里插入图片描述
在这里插入图片描述

界面非常冗杂混乱,如何解决呢。 我们可以通过

代码语言:javascript
复制
	system("pause");
	system("cls");

这两行简单的代码便可以大大优化界面

代码语言:javascript
复制
int main()
{
	int op = -1;
	contact con;
	InitContact(&con);
	do {
		menu();
		printf("请选择你的操作:> \n");
		scanf("%d",&op);
		switch (op)
		{
			case 1:
				AddContact(&con);
				system("pause");
				system("cls");
				break;
			case 2:
				DelContact(&con);
				system("pause");
				system("cls");
				break;
			case 3:
				ModifyContact(&con);
				system("pause");
				system("cls");
				break;
			case 4:
				FindContact(&con);
				system("pause");
				system("cls");
				break;
			case 5:
				ShowContact(&con);
				system("pause");
				system("cls");
				break;
			case 0:
				printf("goodbye~\n");
				system("pause");
				system("cls");
				break;
			default:
				printf("输入格式有误,重新输入:> \n");
				system("pause");
				system("cls");
				break;
		}
	} while (op != 0);

	DestroyContact(&con);

	return 0;
}

让我们看看效果

在这里插入图片描述
在这里插入图片描述

无论进行多少操作,我们的界面依然清爽。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-01-16,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 【通讯录项目 (3 / 3)】基于顺序表的通讯录实现——通讯录项目实现
    • 前言
      • 1 项目预备工作
        • 1.1 多文件处理
        • 1.2 联系人数据管理
      • 2 功能实现
        • 2.1 初始化通讯录
        • 2.2 添加联系人
        • 2.3 删除联系人
        • 2.4 展示通讯录
        • 2.5 查找与修改
        • 2.6 销毁通讯录
      • 3 界面完成
        • 3.1 打印菜单
        • 3.2 完成功能选择
        • 3.3 界面优化
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档