实现动态内存分配的通讯录

实现一个通讯录;
通讯录可以用动态内存分配来存储1000个人的信息,每个人的信息包括:
姓名、性别、年龄、电话、住址
提供方法:
1.    添加联系人信息
2.    删除指定联系人信息
3.    查找指定联系人信息
4.    修改指定联系人信息
5.    显示所有联系人信息
6.    清空所有联系人
7.    以名字排序所有联系人 

首先要实现一个动态内存分配的通讯录,我们需要首先需要一个结构体来保存一个联系人的信息包含姓名性别年龄等,然后还需要一个结构体去保存所有联系人的信息,当前联系人的个数,扩大的容量。

#define _CRT_SECURE_NO_WARNINGS 1  
#include<stdio.h>  
#include<stdlib.h>  
#include<string.h>  
#include<assert.h>  
#define MAX_INIT 10
#define MAX_EXPAND 10
#define MAX_END 1000
void meau()
{
	printf("             *******************************************\n");
	printf("             *******************************************\n");
	printf("             ##############My address book##############\n");
	printf("             *1-Add       2-Delete       3-Find        *\n");
	printf("             *4-Empty     5-Modify       6-Sort        *\n");
	printf("             *0-Exit                     7-Show        *\n");
	printf("             *******************************************\n");
	printf("             *******************************************\n");
}
enum Number//实际上是对一个变量取值范围的限定,花括号内则是它的取值范围如果不赋值,会从赋初值的常量开始依次加一,如果都没有赋值则\从0开始依次加一
{
	Exit,  
	Add,
	Delete,
	Find,
	Empty,
	Modify,
	Sort,
	Show,

} Number_Val;
typedef struct Personal
{
	char name[30];
	char gender[10];
	int age;
	int telephone;
	char address[100];

}Personal;
typedef struct Contacts
{
	Personal *data;    //所有联系人的信息,定义一个指向Personal结构体的指针
	int size;          //当前联系人的个数
	int capacity;

}Contact, **contact;
void Init(contact p)
{
	(*p)->data = (Personal *)malloc(sizeof(Personal)*MAX_INIT);
	if ((*p)->data == NULL)
	{
		printf("out of memory");
		exit(1);
	}
	else
		(*p)->size = 0;    //初始化时联系人个数为0
	(*p)->capacity = MAX_INIT;
}
void Add_linkman(contact p)
{

	if ((*p)->size == (*p)->capacity)
	{
		Personal *temp = (Personal*)realloc((*p)->data, sizeof(Personal)*((*p)->capacity + MAX_EXPAND));
		if (temp == NULL)
		{
			printf("OUT OF MEMORY");
			exit(1);
		}
		else
		{
			(*p)->data = temp;
			(*p)->capacity += MAX_EXPAND;
		}
	}
	printf("请输入姓名:");
	scanf("%s", (*p)->data[(*p)->size].name);//p->data一个指向Personal结构体的指针
	// p->size联系人的个数其实相当于数组的\
							                                  //下标访问模式即输入的表示第几个联系人的信息\
							                                  // 不能写成p->data.name      
	printf("请输入姓别:");
	scanf("%s", (*p)->data[(*p)->size].gender);
	printf("请输入年龄:");
	scanf("%d", &(*p)->data[(*p)->size].age);
	printf("请输入电话:");
	scanf("%d", &(*p)->data[(*p)->size].telephone);
	printf("请输入地址:");
	scanf("%s", (*p)->data[(*p)->size].address);
	(*p)->size++;
}
int  Find_linkman(contact p, char *str);
void Delete_linkman(contact p, char *str)//删除一个联系人的信息其实就是
//信息的覆盖,后一个信息覆盖要删除的信息的位置
{
	int i = 0;
	printf("请输入你要删除的联系人的信息:");
	char name[30];
	scanf("%s", name);
	int ret = Find_linkman(p, name);
	if (ret != -1)
	{
		for (i = ret; i < (*p)->size; i++)
		{
			(*p)->data[i] = (*p)->data[i + 1];
		}
		(*p)->size--;
	}
	else
		printf("该联系人不存在");
}
int  Find_linkman(contact p, char *str)
{
	int i = 0;
	for (i = 0; i < (*p)->size; i++)
	{
		if (strcmp((*p)->data[i].name, str) == 0)
		{
			printf("存在该联系人");
			return i;//存在则返回对应的下标
		}
	}
	printf("不存在该联系人");
	return -1;
}
void Empty_linkman(contact p)
{
	(*p)->size = 0;
}
void Modify_linkman(contact p)
{
	printf("请输入你要修改的联系人的信息:");
	char name[30];
	scanf("%s", name);
	int ret = Find_linkman(p, name);
	if (ret != -1)
	{
		printf("请输入你要修改的联系人的name:");
		scanf("%s", (*p)->data[ret].name);
		printf("请输入你要修改的联系人的gender:");
		scanf("%s", (*p)->data[ret].gender);
		printf("请输入你要修改的联系人的age:");
		scanf("%d", &(*p)->data[ret].age);
		printf("请输入你要修改的联系人的telephone:");
		scanf("%d", &(*p)->data[ret].telephone);
		printf("请输入你要修改的联系人的address:");
		scanf("%s", (*p)->data[ret].address);
	}
}
void show(contact p)
{
	int i = 0;
	for (i = 0; i < (*p)->size; i++)
	{
		printf("name:%s gender:%s age:%d telephone:%d address:%s", \
			(*p)->data[i].name, (*p)->data[i].gender, (*p)->data[i].age, (*p)->data[i].telephone, (*p)->data[i].address);
		printf("\n");
	}

}
void bubbleSort(contact p)
{

	int i = 0;
	for (; i < (*p)->size - 1; i++){
		int j = 0;
		int flag = 0;
		for (j; j < (*p)->size - 1 - i; j++)
		{
			if (strcmp((*p)->data[j].name, (*p)->data[j + 1].name)>0)
			{
				Personal temp = (*p)->data[j];
				(*p)->data[j] = (*p)->data[j + 1];
				(*p)->data[j + 1] = temp;
				//这是将两个结构体之间进行交用
				//创建一个临时结构体的方式变量的方式交换
			}
			flag = 1;//如果一次都没有进行交换则直接跳出循环
		}
		if (!flag)
			break;
	}

}
int main()
{
	meau();
	Contact p;   //定义一个结构体变量
	Contact *q = &p;//这结构体指针必须指向这个结构体变量否则它会成为一个野指针
        Init(&p);
	int input = 0;
	while (1)
	{
		printf("请输入一个数字进行选择:");
		scanf("%d", &input);
		switch (input)
		{

		case Exit:	exit(1); printf("\n"); break;
		case Add:    Add_linkman(w); printf("\n"); break;
		case Delete:  {
						  int num = 0;
						  scanf("%d", &num);
						  Delete_linkman(w, num); printf("\n"); }break;

		case  Find:   {
						  char name[30];
						  scanf("%s", name);
						  Find_linkman(w, name); }; printf("\n"); break;

		case Modify:Modify_linkman(w); printf("\n"); break;
		case Show:show(w); printf("\n"); break;
		case Empty:Empty_linkman(w); printf("\n"); break;
		case Sort:bubbleSort(w); printf("\n"); break;
		default:printf("输入错误!!!");

		}
	}
	free(p);
	system("pause");
	return 0;
}


二:另一种直接给这个结构体开辟内存则不用在调用时再指向它。

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>   
#include<stdlib.h>   
#include<string.h>   
#include<assert.h>   
#define MAX_INIT 10 
#define MAX_EXPAND 10 
#define MAX_END 1000 
void meau()
{
	printf("             *******************************************\n");
	printf("             *******************************************\n");
	printf("             ##############My address book##############\n");
	printf("             *1-Add       2-Delete       3-Find        *\n");
	printf("             *4-Empty     5-Modify       6-Sort        *\n");
	printf("             *0-Exit                     7-Show        *\n");
	printf("             *******************************************\n");
	printf("             *******************************************\n");
}
enum Number
{
	Exit,  //实际上是对一个变量取值范围的限定,花括号内则是它的取值范围\ 
	//如果不赋值,会从赋初值的常量开始依次加一,如果都没有赋值则\ 
	//          从0开始依次加一 
	Add,
	Delete,
	Find,
	Empty,
	Modify,
	Sort,
	Show,
} Number_Val;
typedef struct Personal
{
	char name[30];
	char gender[10];
	int age;
	int telephone;
	char address[100];

}Personal, *personal;
typedef struct Contacts
{
	Personal *data;    //所有联系人的信息,定义一个指向Personal结构体的指针 
	int size;          //当前联系人的个数 
	int capacity;

}Contact, ** contact;
void Init(contact p)    //使用二级指针传参的方式在释放内存的时候不会造成内存的泄漏问题
{
	(*p) = (Contact *)malloc(sizeof(Contact));//相当于*(&p)=p;
	if (*p == NULL)
	{
		printf("out of memory");
		exit(1);
	}

	(*p)->data = (Personal *)malloc(sizeof(Personal)*MAX_INIT);
	if ((*p)->data == NULL)
	{
		printf("out of memory");
		exit(1);
	}
	else
		(*p)->size = 0;    //初始化时联系人个数为0 
	(*p)->capacity = MAX_INIT;
}
void Destory(Contact *p)
{
	free(p->data);
	p->data = NULL;
	p->capacity = 0;
	p->size = 0;
	free(p);
	p = NULL;
}
void Add_linkman(contact p)
{

	if ((*p)->size == (*p)->capacity)
	{
		Personal *temp = (Personal*)realloc((*p)->data, sizeof(Personal)*((*p)->capacity + MAX_EXPAND));
		if (temp == NULL)
		{
			printf("OUT OF MEMORY");
			exit(1);
		}
		else
		{
			(*p)->data = temp;
			(*p)->capacity += MAX_EXPAND;
		}
		if ((*p)->capacity == MAX_END)
		{
			printf("已经有1000个人的通讯录了");
		}
	}
	printf("请输入姓名:");
	scanf("%s", (*p)->data[(*p)->size].name);//p->data一个指向Personal结构体的指针 
	// p->size联系人的个数其实相当于数组的\ 
	//下标访问模式即输入的表示第几个联系人的信息\ 
	// 不能写成p->data.name       
	printf("请输入姓别:");
	scanf("%s", (*p)->data[(*p)->size].gender);
	printf("请输入年龄:");
	scanf("%d", &(*p)->data[(*p)->size].age);
	printf("请输入电话:");
	scanf("%d", &(*p)->data[(*p)->size].telephone);
	printf("请输入地址:");
	scanf("%s", (*p)->data[(*p)->size].address);
	(*p)->size++;
}
int  Find_linkman(contact p, char *str);
void Delete_linkman(contact p, char * str)//删除一个联系人的信息其实就是 
//信息的覆盖,后一个信息覆盖要删除的信息的位置 
{
	int i = 0;
	printf("请输入你要删除的联系人的信息:");
	char name[30];
	scanf("%s", name);
	int ret = Find_linkman(p, name);
	if (ret != -1)
	{
		for (i = ret; i < (*p)->size; i++)
		{
			(*p)->data[i] = (*p)->data[i + 1];
		}
		(*p)->size--;
	}
	else
		printf("该联系人不存在");
}
int  Find_linkman(contact p, char * str)
{
	int i = 0;
	for (i = 0; i < (*p)->size; i++)
	{
		if (strcmp((*p)->data[i].name, str) == 0)
		{
			printf("存在该联系人");
			return i;//存在则返回对应的下标 
		}
	}
	printf("不存在该联系人");
	return -1;
}
void Empty_linkman(contact p)
{
	(*p)->size = 0;
}
void Modify_linkman(contact p)
{
	printf("请输入你要修改的联系人的信息:");
	char name[30];
	scanf("%s", name);
	int ret = Find_linkman(p, name);
	if (ret != -1)
	{
		printf("请输入你要修改的联系人的name:");
		scanf("%s", (*p)->data[ret].name);
		printf("请输入你要修改的联系人的gender:");
		scanf("%s", (*p)->data[ret].gender);
		printf("请输入你要修改的联系人的age:");
		scanf("%d", &(*p)->data[ret].age);
		printf("请输入你要修改的联系人的telephone:");
		scanf("%d", &(*p)->data[ret].telephone);
		printf("请输入你要修改的联系人的address:");
		scanf("%s", (*p)->data[ret].address);
	}
}
void show(contact p)
{
	int i = 0;
	for (i = 0; i < (*p)->size; i++)
	{
		printf("name:%s gender:%s age:%d telephone:%d address:%s", \
			(*p)->data[i].name, (*p)->data[i].gender, (*p)->data[i].age, (*p)->data[i].telephone, (*p)->data[i].address);
		printf("\n");
	}

}
void bubbleSort(contact p)
{

	int i = 0;
	for (; i < (*p)->size - 1; i++){
		int j = 0;
		int flag = 0;
		for (j; j < (*p)->size - 1 - i; j++)
		{
			if (strcmp((*p)->data[j].name, (*p)->data[j + 1].name)>0)
			{
				Personal temp = (*p)->data[j];
				(*p)->data[j] = (*p)->data[j + 1];
				(*p)->data[j + 1] = temp;
				//这是将两个结构体之间进行交用 
				//创建一个临时结构体的方式变量的方式交换 
			}
			flag = 1; //如果一次都没有进行交换则直接跳出循环 
		}
		if (!flag)
			break;
	}

}
int main()
{
	meau(); 
	Contact *p;
	Init(&p);
	int input = 0;
	while (1)
	{
		printf("请输入一个数字进行选择:");
		scanf("%d", &input);
		switch (input)
		{

		case Exit:  exit(1); printf("\n"); break;
		case Add:    Add_linkman(&p); printf("\n"); break;
		case Delete:  {
						  int num = 0;
						  scanf("%d", &num);
						  Delete_linkman(&p, num); printf("\n"); }break;

		case  Find:   {
						  char name[30];
						  scanf("%s", name);
						  Find_linkman(&p, name); }; printf("\n"); break;

		case Modify:Modify_linkman(&p); printf("\n"); break;
		case Show:show(&p); printf("\n"); break;
		case Empty:Empty_linkman(&p); printf("\n"); break;
		case Sort:bubbleSort(&p); printf("\n"); break;
		default:printf("输入错误!!!");

		}
	}
	Destory(p);
	system("pause");
	return 0;
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值