当前位置: 首页 > article >正文

C语言进阶习题【2】(4结构体进阶)——通讯录的实现2

1. 本节实现动态的通讯录实现

在静态版本的基础上,对于通讯录的创建和初始化进行了修改,还修改了add函数,新增了增容函数,和销毁函数。

2. 具体实现

2.0 通讯录创建——动态版本

//动态通讯录版本,空间不够就进行增加
typedef struct Contact
{
	PeoInfo* data;//指向存放通信录中人的信息的空间
	int sz;//当前已经存放的个人信息个数
	int capacity;//记录当前通讯录的最大容量
}Contact;

2.1 通讯录初始化——动态版本

//通讯录初始化——动态版本
void InitContact(Contact* pc)
{
	assert(pc);
	PeoInfo *ptr = (PeoInfo*)calloc( DEFAULT_SZ, sizeof(PeoInfo));//使用calloc不对其进行初始化。
	if (ptr == NULL)
	{
		perror("InitContact::calloc");
		return;
	}
	pc->data = ptr;
	pc->capacity = DEFAULT_SZ;//默认是3个,每次增容增2个
	pc->sz = 0;
}

2.2 增容函数

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

2.3 修改给通讯录中增加联系人函数

//给通讯录中增加联系人信息——动态增长版本
void addContact(Contact* pc)
{
	assert(pc);
	check_capacity(pc);
	//添加联系人信息
	printf("请输入你要增加人的名字:\n");
	scanf("%s", pc->data[pc->sz].name);
	printf("请输入你要增加人的年龄:\n");
	scanf("%d", &(pc->data[pc->sz].age));
	printf("请输入你要增加人的性别:\n");
	scanf("%s", pc->data[pc->sz].sex);
	printf("请输入你要增加人的地址:\n");
	scanf("%s", pc->data[pc->sz].addr);
	printf("请输入你要增加人的电话:\n");
	scanf("%s", pc->data[pc->sz].tele);

	pc->sz++;
}

2.4 销毁函数

我们动态申请了内存,就一定要释放

//销毁通讯录
void destroyContact(Contact* pc)
{
	free(pc->data);
	pc->data = NULL;
	pc->capacity = NULL;
	pc->sz = 0;
	pc = NULL;
	printf("销毁成功\n");
}

2.5 验证

在这里插入图片描述

3. 源代码

3.1 contact.h

#define _CRT_SECURE_NO_WARNINGS 1
#pragma once

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


#define MAX 100
#define NAME_MAX 20
#define SEX_MAX 5
#define ADDR_MAX 24
#define TELE_MAX 12

#define DEFAULT_SZ 3
#define INC_SZ 2

typedef struct PeoInfo
{
	char name[NAME_MAX];
	int age;
	char sex[SEX_MAX];
	char addr[ADDR_MAX];
	char tele[TELE_MAX];
}PeoInfo;

//静态通讯录版本
//typedef struct Contact
//{
//	PeoInfo data[MAX];//存放通信录中人的信息
//	int sz;//当前已经存放的个人信息
//}Contact;

//动态通讯录版本,空间不够就进行增加
typedef struct Contact
{
	PeoInfo* data;//指向存放通信录中人的信息的空间
	int sz;//当前已经存放的个人信息个数
	int capacity;//记录当前通讯录的最大容量
}Contact;

//通讯录初始化
void InitContact(Contact* pc);
//销毁通讯录
void destroyContact(Contact* pc);

//给通讯录中增加联系人信息
void addContact(Contact* pc);
//删除通讯录中指定联系人信息
void delContact(Contact* pc);
//查找通讯录中联系人信息
void serchContact(Contact* pc);
//修改联系人信息
void mdifyContact(Contact* pc);
//展示通讯录中的信息
void showContact(Contact* pc);
//清空联系人信息
void clearContact(Contact* pc);
//排序联系人信息
void sortContact(Contact* pcon);

3.2 contact.c

#define _CRT_SECURE_NO_WARNINGS 1
#include "contact.h"

//通讯录初始化——静态版本
//void InitContact(Contact* pc)
//{
//	assert(pc);
//	memset(pc->data, 0, sizeof(pc->data));
//	pc->sz = 0;
//}
//通讯录初始化——动态版本
void InitContact(Contact* pc)
{
	assert(pc);
	PeoInfo *ptr = (PeoInfo*)calloc( DEFAULT_SZ, sizeof(PeoInfo));//使用calloc不对其进行初始化。
	if (ptr == NULL)
	{
		perror("InitContact::calloc");
		return;
	}
	pc->data = ptr;
	pc->capacity = DEFAULT_SZ;//默认是3个,每次增容增2个
	pc->sz = 0;
}
//销毁通讯录
void destroyContact(Contact* pc)
{
	free(pc->data);
	pc->data = NULL;
	pc->capacity = NULL;
	pc->sz = 0;
	pc = NULL;
	printf("销毁成功\n");
}

//给通讯录中增加联系人信息——静态版本
//void addContact(Contact* pc)
//{
//	assert(pc);
//	if (pc->sz == MAX)
//	{
//		printf("通讯录已满,无法添加\n");
//		return;
//	}
//	//添加联系人信息
//	printf("请输入你要增加人的名字:\n");
//	scanf("%s", pc->data[pc->sz].name);
//	printf("请输入你要增加人的年龄:\n");
//	scanf("%d", &(pc->data[pc->sz].age));
//	printf("请输入你要增加人的性别:\n");
//	scanf("%s", pc->data[pc->sz].sex);
//	printf("请输入你要增加人的地址:\n");
//	scanf("%s", pc->data[pc->sz].addr);
//	printf("请输入你要增加人的电话:\n");
//	scanf("%s", pc->data[pc->sz].tele);
//	
//	pc->sz++;
//}
 
void check_capacity(Contact* pc)
{
	if (pc->sz == pc->capacity)
	{
		PeoInfo* ptr = (PeoInfo * )realloc(pc->data, pc->capacity * sizeof(PeoInfo));
		if (ptr == NULL)
		{
			perror("check_capacity::realloc");
			return;
		}
		pc->data = ptr;
		pc->capacity += INC_SZ;
		printf("增容成功!\n");
	}
}
 
//1. 给通讯录中增加联系人信息——动态增长版本
void addContact(Contact* pc)
{
	assert(pc);
	check_capacity(pc);
	//添加联系人信息
	printf("请输入你要增加人的名字:\n");
	scanf("%s", pc->data[pc->sz].name);
	printf("请输入你要增加人的年龄:\n");
	scanf("%d", &(pc->data[pc->sz].age));
	printf("请输入你要增加人的性别:\n");
	scanf("%s", pc->data[pc->sz].sex);
	printf("请输入你要增加人的地址:\n");
	scanf("%s", pc->data[pc->sz].addr);
	printf("请输入你要增加人的电话:\n");
	scanf("%s", pc->data[pc->sz].tele);

	pc->sz++;
}

//查找指定条目下标
int FindByName(const Contact* pc, char name[])
{
	assert(pc);
	int i = 0;
	for (i = 0; i < pc->sz; i++)
	{
		if (strcmp((pc->data[i]).name, name) == 0)
		{
			return i;
		}
	}
	return -1;
}

//2. 删除通讯录中指定联系人信息
void delContact(Contact* pc)
{
	assert(pc);
	char name[NAME_MAX] = { 0 };
	if (pc->sz == 0)
	{
		printf("通讯录是空的,无法删除\n");
		return;
	}
	//找到要删除的人信息
	printf("请输入要删除人的名字:\n");
	scanf("%s", name);
	int pos = FindByName(pc, name);
	if (pos == -1)
	{
		printf("要删除的人名字不存在\n");
		return;
	}
	//删除 走到这里说明找到了,并且位置是pos
	int i = 0;
	for (i = pos; i < pc->sz - 1; i++)
	{
		pc->data[i] = pc->data[i + 1];
	}
	pc->sz--;
	printf("删除成功\n");
}

//3. 查找通讯录中联系人信息
void serchContact(Contact* pc)
{
	assert(pc);
	char name[NAME_MAX] = { 0 };
	printf("请输入您想查找联系人的名字:\n");
	scanf("%s", name);
	int pos = FindByName(pc, name);
	if (pos == -1)
	{
		printf("您所查找的联系人不在本通讯录中:\n");
	}
	//打印联系人信息
	printf("%-20s\t%-4s\t%-5s\t%-20s\t%-12s\n", "名字", "年龄", "性别", "地址", "电话");
	printf("%-20s\t%-4d\t%-5s\t%-20s\t%-12s\n", pc->data[pos].name,
		pc->data[pos].age,
		pc->data[pos].sex,
		pc->data[pos].addr,
		pc->data[pos].tele);
}

//4.修改指定联系人信息
void mdifyContact(Contact* pc)
{
	assert(pc);
	char name[NAME_MAX] = { 0 };
	printf("请输入要修改人的名字:>");
	scanf("%s", name);
	int pos = FindByName(pc, name);
	if (-1 == pos)
	{
		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].addr);
	printf("请输入电话:>");
	scanf("%s", pc->data[pos].tele);

	printf("修改完成\n");
}
//5. 展示通讯录中的信息
void showContact(Contact* pc)
{
	assert(pc);
	int i = 0;
	printf("%s\t%s\t%s\t%s\t%s\n", "姓名", "年龄", "性别", "地址", "电话");
	for (i = 0; i < pc->sz; i++)
	{
		printf("%s\t%d\t%s\t%s\t%s\n", (pc->data)[i].name,
			(pc->data)[i].age,
			(pc->data)[i].sex,
			(pc->data)[i].addr,
			(pc->data)[i].tele);
	}
}


//6、清空所有联系人信息
void clearContact(Contact* pc)
{
	InitContact(pc);
}


//7、按名字排序所有联系人信息
void sortContact(Contact* pc)
{
	int i = 0;
	int j = 0;
	PeoInfo tem ;
	for (i = 0; i < pc->sz; i++)
	{
		for (j = 0; j < pc->sz - 1 - i; j++)
		{
			if (strcmp((pc->data[j].name), pc->data[j + 1].name))
			{
				tem = pc->data[j];
				pc->data[j] = pc->data[j + 1];
				pc->data[j + 1] = tem;
			}
		}
	}

}

3.1 test.c

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include "contact.h"

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

enum Option
{
	EXIT,
	ADD,
	DEL,
	SEARCH,
	MODIFY,
	SHOW,
	CLEAR,
	SORT
};


int main()
{
	int input = 0;
	//创建通讯录
	Contact con;
	InitContact(&con);
	do {
		manu();
		printf("请输入您的选择:>\n");
		
		scanf("%d", &input);
		switch (input)
		{
		case ADD:
			addContact(&con);
			break;
		case DEL:
			delContact(&con);
			break;
		case SEARCH:
			serchContact(&con);
			break;
		case MODIFY:
			mdifyContact(&con);
			break;
		case SHOW:
			showContact(&con);
			break;
		case CLEAR:
			clearContact(&con);
			break;
		case SORT:
			sortContact(&con);
			break;
		case EXIT:
			destroyContact(&con);
			printf("您已退出\n");
			break;
		default:
			printf("您的输入有误,请重新输入:\n");
			break;
		}
	} while (input);
	return 0;
}





http://www.kler.cn/a/550441.html

相关文章:

  • hive全量迁移脚本
  • 计算光学基础
  • 【设计模式】【结构型模式】桥接模式(Bridge)
  • VueRouter 实例
  • 基于Flask的广西高校舆情分析系统的设计与实现
  • 深入理解 Shell 脚本执行方式:`source`、`./xx.sh`、`bash xx.sh` 和 `sh xx.sh`
  • leetcode88.合并两个有序数组
  • CMake configure_file
  • 数字水印嵌入及提取系统——基于小波变换GUI
  • 基于springcloud微服务架构的巡游出租管理平台
  • JDK、Nginx、Kafka、Zookeeper安装部署
  • 网络安全专业好就业吗?
  • 【力扣】114.二叉树展开为链表
  • 使用神经网络对驾驶数据进行道路类型分类
  • TCP/IP参考模型之区别(Differences Between the OSI and TCP/IP Reference Models)
  • python下载文件
  • QML 部件获得焦点触发的全局槽函数 onActiveFocusItemChanged
  • Android车机DIY开发之软件篇(十七) Android模拟器移植Automotive
  • 使用 AbilityKit 创建服务卡片
  • iOS 中使用 FFmpeg 的高级功能 - 滤镜(Filters)