动态通讯录

一.动态通讯录的设计

        在之前已经实现静态的通讯录,接下来要对静态通讯录进行改造,将通讯录变成可以动态增长空间。

二、通讯录的改造

        2.1 通讯录结构体改造

        data是用于指向联系人的指针,sz是通讯录当前的长度,capacity是通讯录的最大容量。

typedef struct Contact
{
	PeoInfo* data;
	int sz;
	int capacity; //最大容量
}Contact;

        2.2 初始化通讯录功能的改造

        先判断指针是否可用,再给指针的data开辟默认大小的空间,将长度和最大容量设为默认值。

void InitContact(Contact* p)
{
	assert(p);
	p->data = (PeoInfo*)malloc(DEFAULT_SZ * sizeof(PeoInfo));
	if (p->data == NULL)
	{
		perror("InitContact");
		return;
	}
	p->sz = 0;
	p->capacity = DEFAULT_SZ;
}

        2.3 添加联系人功能的改造

        设计一个判断空间是否已满的函数若已满则用realloc函数修改空间的大小,扩容成功后调整最大容量大小,再给通讯录添加联系人。

int CheckCapacity(Contact* p)
{
	if (p->sz == p->capacity)
	{
		PeoInfo* ptr = (PeoInfo*)realloc(p->data,(p->capacity + ADD_SZ) * sizeof(PeoInfo));
		if (ptr == NULL)
		{
			perror("CheckCapacity");
			return 0;
		}
		else
		{
			p->data = ptr;
			p->capacity += ADD_SZ;
			printf("扩容成功\n");
			return 1;
		}
	}
	return 1;
}

void AddContach(Contact* p)
{
	assert(p);
	if (CheckCapacity(p) == 0)
	{
		return;
	}
	printf("请输入姓名:");
	scanf("%s", p->data[p->sz].name);
	printf("请输入年龄:");
	scanf("%d", &(p->data[p->sz].age));
	printf("请输入性别:");
	scanf("%s", p->data[p->sz].sex);
	printf("请输入电话:");
	scanf("%s", p->data[p->sz].tele);
	printf("请输入地址:");
	scanf("%s", p->data[p->sz].addr);


	p->sz++;
	printf("成功添加联系人\n");
}

三、添加的通讯录功能

        因为不对开辟的空间释放会导致内存泄漏等问题,因此要设计一个函数用于释放内存。

void DestroyContact(Contact* p)
{
	free(p->data);
	p->data = NULL;
	p->capacity = 0;
	p->sz = 0;
}

四、代码一览

       4.1 test.c

#define _CRT_SECURE_NO_WARNINGS 1

#include "contact.h"


void menu()
{
	printf("***********************************\n");
	printf("**** 1.添加       2.删除  *********\n");
	printf("**** 3.查找       4.修改  *********\n");
	printf("**** 5.显示       6.排序  *********\n");
	printf("**** 0.退出               *********\n");
	printf("***********************************\n");
}


void test()
{
	int input = 0;
	Contact con;

	InitContact(&con);
	do
	{
		menu();
		printf("请选择操作:");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			AddContach(&con);
			break;
		case 2:
			DelContach(&con);
			break;
		case 3:
			SearchContach(&con);
			break;
		case 4:
			ModifyContach(&con);
			break;
		case 5:
			ShowContach(&con);
			break;
		case 6:
			SortContach(&con);
			break;
		case 0:
			DestroyContact(&con);
			printf("已退出!\n");
			break;
		default:
			printf("输入错误请重新输入!\n");
			break;
		}

	} while (input);
}



int main()
{
	test();
	return 0;
	
}

     4.2 contact.h

#pragma once
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <assert.h>
#include <string.h>
#include<stdlib.h>

#define MAX 100  //通讯录大小
#define MAX_name 30
#define MAX_sex 5
#define MAX_tele 12
#define MAX_addr 40

#define DEFAULT_SZ 3
#define ADD_SZ 2

//声明结构体类型
typedef struct PeoInfo
{
	char name[MAX_name];
	int age;
	char sex[MAX_sex];
	char tele[MAX_tele];
	char addr[MAX_addr];
}PeoInfo;

//通讯录
//静态版本
//typedef struct Contact
//{
//	PeoInfo data[MAX];
//	int sz;
//}Contact;

typedef struct Contact
{
	PeoInfo* data;
	int sz;
	int capacity; //最大容量
}Contact;


//函数声明


//初始化通讯录
void InitContact(Contact *p);

//添加联系人信息
void AddContach(Contact* p);

//显示联系人信息
void ShowContach(Contact* p);

//删除联系人信息
void DelContach(Contact* p);

//查找联系人
void SearchContach(const Contact* p);


//修改联系人信息
 void ModifyContach(Contact* p);


 //按姓名排序联系人
 void SortContach(Contact* p);

 //释放
 void DestroyContact(Contact* p);

        4.3 contact.c


#include "contact.h"
int CheckCapacity(Contact* p);
//静态初始化
//void InitContact(Contact* p)
//{
//	assert(p);
//	for (int i = 0; i < MAX; i++)
//	{
//		strcpy(p->data[i].name, "0");
//		p->data[i].age=0;
//		strcpy(p->data[i].sex, "0");
//		strcpy(p->data[i].addr, "0");
//		strcpy(p->data[i].tele, "0");
//	}
//	p->sz= 0;
//}




//动态初始化
void InitContact(Contact* p)
{
	assert(p);
	p->data = (PeoInfo*)malloc(DEFAULT_SZ * sizeof(PeoInfo));
	if (p->data == NULL)
	{
		perror("InitContact");
		return;
	}
	p->sz = 0;
	p->capacity = DEFAULT_SZ;
	//加载
	LoadContact(p);
}



//扩容
int CheckCapacity(Contact* p)
{
	if (p->sz == p->capacity)
	{
		PeoInfo* ptr = (PeoInfo*)realloc(p->data,(p->capacity + ADD_SZ) * sizeof(PeoInfo));
		if (ptr == NULL)
		{
			perror("CheckCapacity");
			return 0;
		}
		else
		{
			p->data = ptr;
			p->capacity += ADD_SZ;
			printf("扩容成功\n");
			return 1;
		}
	}
	return 1;
}

//静态版本
//void AddContach(Contact* p)
//{
//	assert(p);
//	if (p->sz == MAX)
//	{
//		printf("通讯录已满,无法添加!\n");
//		return;
//	}
//	printf("请输入姓名:");
//	scanf("%s", p->data[p->sz].name);
//	printf("请输入年龄:");
//	scanf("%d", &(p->data[p->sz].age));
//	printf("请输入性别:");
//	scanf("%s", p->data[p->sz].sex);
//	printf("请输入电话:");
//	scanf("%s", p->data[p->sz].tele);
//	printf("请输入地址:");
//	scanf("%s", p->data[p->sz].addr);
//
//
//	p->sz++;
//	printf("成功添加联系人\n");
//}

//动态版本
void AddContach(Contact* p)
{
	assert(p);
	if (CheckCapacity(p) == 0)
	{
		return;
	}
	printf("请输入姓名:");
	scanf("%s", p->data[p->sz].name);
	printf("请输入年龄:");
	scanf("%d", &(p->data[p->sz].age));
	printf("请输入性别:");
	scanf("%s", p->data[p->sz].sex);
	printf("请输入电话:");
	scanf("%s", p->data[p->sz].tele);
	printf("请输入地址:");
	scanf("%s", p->data[p->sz].addr);


	p->sz++;
	printf("成功添加联系人\n");
}

void ShowContach(Contact* p)
{
	assert(p);
	printf("%-10s\t%-4s\t%-5s\t%-12s\t%-30s\n", "名字", "年龄", "性别", "电话", "地址");
	for (int i = 0; i < p->sz; i++)
	{
		printf("%-10s\t%-4d\t%-5s\t%-12s\t%-30s\n",
			p->data[i].name,
			p->data[i].age,
			p->data[i].sex,
			p->data[i].tele,
			p->data[i].addr);
	}
}


static int Findname(const Contact* p, char name[])
{
	int i = 0;
	for (i = 0; i < p->sz; i++)
	{
		if (strcmp(p->data[i].name, name) == 0)
		{
			return i;  //找到
		}
	}
	return -1;   //没找到
}




void DelContach(Contact* p)
{
	assert(p);
	if (p->sz == 0)
	{
		printf("通讯录为空,无法删除\n");
		return;
	}
	char name[MAX_name] = {0};
	printf("请输入删除人的名字:");
	scanf("%s", name);
	/*int i = 0;
	int del = 0;
	int flag = 0;
	for (i = 0; i < p->sz;i++)
	{
		if (strcmp(p->data[i].name, name)==0)
		{
			del = i;
			flag = 1;
			break;
		}
	}
	if (flag == 0)
	{
		printf("没有此人\n");
		return;
	}*/

	int del = Findname(p, name);
	if(del == -1)
	{
		printf("没有此人\n");
		return;
	}
	int i = 0;
	for (i = del; i < p->sz - 1; i++)
	{
		p->data[i] = p->data[i + 1];
	}
	printf("成功删除\n");
	p->sz--;

}


void SearchContach(const Contact* p)
{
	assert(p);
	char name[MAX_name];
	printf("请输入查找人的名字:");
	scanf("%s", name);
	int sear = Findname(p, name);
	if (sear == -1)
		printf("没有此人");
	else
		printf("%-10s\t%-4d\t%-5s\t%-12s\t%-30s\n",
			p->data[sear].name,
			p->data[sear].age,
			p->data[sear].sex,
			p->data[sear].tele,
			p->data[sear].addr);
}


void ModifyContach(Contact* p)
{
	assert(p);
	char name[MAX_name];
	printf("请输入修改人的名字:");
	scanf("%s", name);
	int modi = Findname(p, name);
	if (modi == -1)
		printf("没有此人");
	else
	{
		printf("请输入姓名:");
		scanf("%s", p->data[modi].name);
		printf("请输入年龄:");
		scanf("%d", &(p->data[modi].age));
		printf("请输入性别:");
		scanf("%s", p->data[modi].sex);
		printf("请输入电话:");
		scanf("%s", p->data[modi].tele);
		printf("请输入地址:");
		scanf("%s", p->data[modi].addr);

		printf("修改成功\n");
	}
}


void SortContach(Contact* p)
{
	assert(p);
	if (p->sz == 0)
	{
		printf("表空,无法排序\n");
		return;
	}
	PeoInfo temp;
	int i = 0;
	int j = 0;
	for (i = 0; i < p->sz; i++)
	{
		for(j = 0; j < p->sz - i - 1; j++)
		{
			if (strcmp(p->data[j].name, p->data[j + 1].name) > 0)
			{
				temp = p->data[j];
				p->data[j] = p->data[j + 1];
				p->data[j + 1] = temp;
			}
		}
	}
	printf("排序成功\n");
}

void DestroyContact(Contact* p)
{
	free(p->data);
	p->data = NULL;
	p->capacity = 0;
	p->sz = 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值