IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> C语言题目——通讯录(静态存储+动态存储) -> 正文阅读

[C++知识库]C语言题目——通讯录(静态存储+动态存储)

目录

通讯录基本要求:

实现功能:

一、打印菜单:

二、联系人信息存储

三、通讯录初始化及功能:

1、静态存储通讯录

(1)、通讯录信息:

(2)、初始化通讯录:

(3)、通讯录功能:

2、动态存储通讯录

(1)、通讯录信息:

(2)、初始化通讯录:

(3)、通讯录功能:

四、通讯录主函数:


通讯录基本要求:

??????????????????????????????????????? ? ?存储人数:100

? ? ? ? ? ? ? ? ? ? ? ? ? ???人员信息:?姓名、性别、年龄、电话、住址

实现功能:

????????????????????????添加联系人信息

????????????????????????删除联系人信息

????????????????????????查找联系人信息

????????????????????????修改联系人信息

????????????????????????显示联系人信息

? ? ? ? ????????????????按名字排序所有联系人

一、打印菜单:

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

二、联系人信息存储

先定义一个peoinfo的结构体
,用来存放联系人的基本信息,成员包括name、sex、tele、age、addr。

//联系人信息:
struct peoinfo
{
	char name[MAX_NAME];
	char sex[MAX_SEX];
	char tele[MAX_TELE];
	int age;
	char addr[MAX_ADDR];

};

??

三、通讯录初始化及功能:

1、静态存储通讯录

(1)、通讯录信息:

然后再定义一个contact的结构体,里面用来存放结构体peoinfo 和通讯录内联系人的个数sz。

struct contact
{
	struct peoinfo data[MAX];
	int sz;
};

?

(2)、初始化通讯录:

void initcontact(struct contact* pc)
{
	assert(pc);
	pc->sz = 0;
	memset(pc->data, 0, MAX * sizeof(struct peoinfo));
}

初始化时先断言是否为空。然后分开初始化,利用结构体的访问形式pc->sz = 0,对于数组,我们利用内存设置函数memset来初始化,以字节为单位一个字节一个字节的初始化!

(3)、通讯录功能:

? ? ? ? 1.添加联系人

在添加新的联系人时,首先断言是否为空;然后要看通信录是否还有空间,进行通讯录是否为满判断,若没有空间则结束进程,若有空间则输入个人的信息存储到数组里;添加完成后sz++

void addcontact(struct 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");
}

? ? ? ? 2.删除联系人

删除联系人之前先进行按姓名的人员查找,包括下面的查找联系人、修改联系人都需要用到这个查找,所以我们就不妨封装一个函数——遍历整个数组通过名字来进行查找,找到就返回下标,找不到返回-1;

通过查找函数先判断通讯里面是否存在人员,不存在就不需要操作,结束进程;若存在则删除表中人员的信息——只需要把ret后的数据依次往前移动,覆盖掉前一个位置的信息就可以了。删除成功后把sz--。

int findname(const struct contact* pc, char name[])
{
	for (int i = 0; i < pc->sz; i++)
		if (0 == strcmp(pc->data[i].name, name))
			return i;
	return -1;
}
void delecontact(struct contact* pc)
{
	char name[MAX_NAME];
	printf("请输入要删除的联系人姓名:");
	scanf("%s", name);
	int ret = findname(pc, name);
	if (ret == -1)
		printf("不存在!!!\n");
	else
	{
		pc->data[ret] = pc->data[pc->sz];
		pc->sz--;
		printf("删除成功\n");
	}
}

????????3.查找联系人

运用之前的查找函数根据姓名进行查找,若返回-1则找不到结束进程;若找到了,根据返回的ret下标,打印信息即可!

void searchcontact(const struct contact* pc)
{
	char name[MAX_NAME];
	printf("输入要查找的人姓名:");
	scanf("%s", name);
	int ret = findname(pc, name);
	if (ret == -1)
		printf("要查找的人不存在!\n");
	else
	{
		printf("%-20s\t%-5s\t%-5s\t%-12s\t%-30s\n", "姓名","性别", "年龄", "电话", "地址");
		printf("%-20s\t%-5s\t%-5d\t%-12s\t%-30s\n", pc->data[ret].name,
			pc->data[ret].sex,
			pc->data[ret].age,
			pc->data[ret].tele,
			pc->data[ret].addr);
	}
}

? ? ? ? 4.展示联系人

首先先打印一个标题,增加可读性!然后在利用for循环打印信息。默认是左对齐的、负号代表右对齐。所以在这里为了美观性我们可以用负号进行右对齐

void showcontact(const struct contact* pc)
{
	printf("%-20s\t%-5s\t%-5s\t%-12s\t%-30s\n", "姓名", "性别", "年龄", "电话", "地址");
	for (int i = 0; i < pc->sz; i++)
	{
		printf("%-20s\t%-5s\t%-5d\t%-12s\t%-30s\n", pc->data[i].name,
			pc->data[i].sex,
			pc->data[i].age,
			pc->data[i].tele,
			pc->data[i].addr);
	}
}

? ? ? ? 5.修改联系人

通过查找函数根据姓名进行查找,找不到就返回-1结束进程;找到了则根据返回的下标ret,再次输入信息覆盖之前的信息。

void modifycontact(struct contact* pc)
{
	printf("请输入要修改的人的姓名:");
	char name[MAX_NAME];
	scanf("%s", name);
	int ret = findname(pc, name);
	if (ret == -1)
		printf("要修改的人不存在!!!\n");
	else
	{
		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("修改成功!!!");

	}
}

? ? ? ? 6.按照联系人姓名排序

在这里我们可以运用 qsort() 函数进行排序!

int cmpname(const void* p1, const void* p2)
{
	return(strcmp(((struct peoinfo*)p1)->name, ((struct peoinfo*)p2)->name));
}
void sortcontact(struct contact* pc)
{
	qsort(pc->data, pc->sz, sizeof(struct peoinfo), cmpname);
}

?注:这个通讯录我们采用静态存储的模式即顺序表的方式来实现,但是静态存储的通讯录对于内存的利用不是很有效,存在着一些明显的弊端,当存储人数少时,存在空间浪费现象;当人数达到设置值时便不能再进行存储,存在空间不足的现象。因此下面的动态存储通讯录便是基于此的优化!?

2、动态存储通讯录

(1)、通讯录信息:

相比于静态存储,这里可以利用指针动态创建内存,此外还增加了一个变量来记录当前内存的容量

struct contact
{
	struct peoinfo *data; //指向了存放数据的空间
	int sz;				 //已经放进去的信息
	int capacity;		 //容量
};

?

(2)、初始化通讯录:

void initcontact(struct contact* pc)
{
	assert(pc);
	pc->data = (struct peoinfo*)malloc(DEFAULT_SZ * sizeof(struct peoinfo));
	if (pc->data == NULL)
	{
		perror("initcontact");
		return;
	}
	pc->sz = 0;
	pc->capacity = DEFAULT_SZ;
}

(3)、通讯录功能:

? ? ? ? 1.添加联系人

static int check_capacity(struct contact* pc)
{
	if (pc->sz == pc->capacity)
	{
		//增加容量
		struct peoinfo* ptr = realloc(pc->data, (pc->capacity + INC_SZ) * sizeof(struct peoinfo));
		if (ptr != NULL)
		{
			pc->data = ptr;
			pc->capacity += INC_SZ;
			printf("增容成功!\n");
			return 1;
		}
		else
		{
			perror("addcontact");
			return 0;
		}
	}
	else
		return 1;
}
void addcontact(struct contact* pc)
{
	assert(pc);
	
	if (0 == check_capacity(pc))
	{
		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");
}

? ? ? ? 2.删除联系人

void delecontact(struct contact* pc)
{
	char name[MAX_NAME];
	printf("请输入要删除的联系人姓名:");
	scanf("%s", name);
	int ret = findname(pc, name);
	if (ret == -1)
		printf("不存在!!!\n");
	else
	{
		for (int j = ret; j < pc->sz - 1; j++)
		{
			pc->data[j] = pc->data[j + 1];
		}
		pc->sz--;
		printf("成功删除指定联系人\n");
	}
}

????????3.查找联系人

void searchcontact(const struct contact* pc)
{
	char name[MAX_NAME];
	printf("输入要查找的人姓名:");
	scanf("%s", name);
	int ret = findname(pc, name);
	if (ret == -1)
		printf("要查找的人不存在!\n");
	else
	{
		printf("%-20s\t%-5s\t%-5s\t%-12s\t%-30s\n", "姓名", "性别", "年龄", "电话", "地址");
		printf("%-20s\t%-5s\t%-5d\t%-12s\t%-30s\n", pc->data[ret].name,
			pc->data[ret].sex,
			pc->data[ret].age,
			pc->data[ret].tele,
			pc->data[ret].addr);
	}
}

? ? ? ? 4.展示联系人

void showcontact(const struct contact* pc)
{
	printf("%-20s\t%-5s\t%-5s\t%-12s\t%-30s\n", "姓名", "性别", "年龄", "电话", "地址");
	for (int i = 0; i < pc->sz; i++)
	{
		printf("%-20s\t%-5s\t%-5d\t%-12s\t%-30s\n", pc->data[i].name,
			pc->data[i].sex,
			pc->data[i].age,
			pc->data[i].tele,
			pc->data[i].addr);
	}
}

? ? ? ? 5.修改联系人

void modifycontact(struct contact* pc)
{
	printf("请输入要修改的人的姓名:");
	char name[MAX_NAME];
	scanf("%s", name);
	int ret = findname(pc, name);
	if (ret == -1)
		printf("要修改的人不存在!!!\n");
	else
	{
		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("修改成功!!!");
	}
}

? ? ? ? 6.按照联系人姓名排序

int cmpname(const void* p1, const void* p2)
{
	return(strcmp(((struct peoinfo*)p1)->name, ((struct peoinfo*)p2)->name));
}
//按照姓名来排序
void sortcontact(struct contact* pc)
{
	qsort(pc->data, pc->sz, sizeof(struct peoinfo), cmpname);
}

????????7.销毁通讯录?

释放pc->data指针,并手动置为NULL,把sz和capacity置为0

销毁通讯录可以不写在菜单里,直接写到退出通讯录里面,当退出时直接调用这个销毁函数。

void destroycontact(struct contact* pc)
{
	free(pc->data);
	pc->data = NULL;
	pc->capacity = 0;
	pc->sz = 0;
}

四、通讯录主函数:

int main()
{
	int input = 0;
	struct contact con;
	//初始化
	initcontact(&con);
	do
	{
		menu();
		printf("输入选择:");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			addcontact(&con);
			break;
		case 2:
			delecontact(&con);
			break;
		case 3:
			searchcontact(&con);
			break;
		case 4:
			modifycontact(&con);
			break;
		case 5:
			showcontact(&con);
			break;
		case 6:
			sortcontact(&con);
			break;
		case 0:
			//destroycontact(&con);    //动态存储时使用
			printf("退出");
			break;
		default:
			printf("输入错误");
			break;
		}
	} while (input);

	return 0;
}

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-09-25 23:05:06  更:2022-09-25 23:05:13 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/19 14:52:00-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码