通讯录(静态+动态)

文章目录

  • 一、静态通讯录
    • 1.contact.h
    • 2. contact.c
    • 3.test.c
  • 二、动态内存通讯录
    • 1.contact.h
    • 2.contact.c
    • 3. test.c

一、静态通讯录

主要是嵌套调用关于一个人信息的机构体数组

1.contact.h

主要是类型的定义和函数的声明

#define _CRT_SECURE_NO_WARNINGS
#define max 1000
#include
#include
struct people
{
	char name[20];
	int age;
	char sex[20];
	char tele[20];
	char addr[20];
};
typedef struct contact
{
	struct people data[max];
	int sz;
}contact;
void init(contact* p);//初始化
void addcontact(contact* p);//增加
void delcontact(contact* p);//删除
void searchcontact(const contact* p);//这里我们只是寻找数据 不修改 用const修饰结构体本身内容不能被修改 起到保护数据的作用
void modifycontact(contact* p);//修改
void printcontact(contact* p);//打印
void sortcontact(contact* p);//排序--按照名字来排

2. contact.c

函数的实现

#include"contact.h"
void init(contact* p)//初始化
{
	p->sz = 0;
	memset(p->data, 0, sizeof(p->data));//将整个结构体数组中的元素全部初始化为0
}
void addcontact(contact* 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++;
}
int find(contact*p,char name[])
{
	int i = 0;
	for (i = 0; i < p->sz; i++)
	{
		if (strcmp(name, p->data[i].name) == 0)
		{
			return i;
		}
	}
	return -1;
}
void delcontact(contact* p)//删除通讯录成员
{
	if (p->sz == 0)
	{
		printf("没有数据可以删除\n");
		return;
	}
	char name[20];
	printf("请删除输入名字:>");
	scanf("%s", name);
	int ret=find(p,name);
	if (ret == -1)
	{
		printf("没找到\n");
		return;
	}
	else
	{
		int i = 0;
		for (i = 0; i < p->sz - 1; i++)//数据到达倒数第二个就会把倒数第一个数传过来
		{
			p->data[i] = p->data[i + 1];
		}
		p->sz--;//一共有两个倒数第一个的数的值 故删去最后一个数
	}
}
void searchcontact(const contact* p)//查找通讯录成员
{
	char name[20];
	printf("输入要查找的名字:>");
	scanf("%s", name);
	int ret=find(p, name);
	if (ret == -1)
	{
		printf("没找到\n");
		return;
	}
	else
	{
		printf("%20s\t %5s\t %5s\t %20s\t %20s\n", "名字", "年龄", "性别", "电话", "地址");
		printf("%20s\t", p->data[ret].name);
		printf("%5d\t", p->data[ret].age);
		printf("%5s\t", p->data[ret].sex);
		printf("%20s\t", p->data[ret].tele);
		printf("%20s\n", p->data[ret].addr);
	}
}
void modifycontact(contact* p)//修改通讯录成员
{
	char name[20];
	printf("输入名字:>");
	scanf("%s", name);
	int ret=find(p, name);
	if (ret == -1)
	{
		printf("没找到该成员\n");
	}
	else
	{
		printf("请输修改入名字:>");
		scanf("%s", p->data[ret].name);
		printf("请输入修改年龄:>");
		scanf("%d", &p->data[ret].age);
		printf("请输入修改性别:>");
		scanf("%s", p->data[ret].sex);
		printf("请输入修改电话:>");
		scanf("%s", p->data[ret].tele);
		printf("请输入修改地址:>");
		scanf("%s", p->data[ret].addr);
	}
}
void printcontact(contact* p)//输出所有成员
{
	int i = 0;
	printf("%20s\t %5s\t %5s\t %20s\t %20s\n", "名字", "年龄", "性别", "电话", "地址");
	for (i = 0; i < p->sz; i++)
	{
		printf("%20s\t", p->data[i].name);
		printf("%5d\t", p->data[i].age);
		printf("%5s\t", p->data[i].sex);
		printf("%20s\t", p->data[i].tele);
		printf("%20s\n", p->data[i].addr);
	}
}
void sortcontact(contact* p)//将结构体成员排序
{
	int i = 0;//类似冒泡排序 将比较改成字符串比较的方法 
	int j = 0;//比较两个名字的大小 来交换两个结构体中所有的东西
	for (i = 0; i < p->sz - 1; i++)
	{
		for (j = 0; j < p->sz - 1 - i; j++)
		{
			if (strcmp(p->data[j].name, p->data[j+1].name) > 0)
			{
				struct people tmp  = p->data[j];
				p->data[j] = p->data[j + 1];
				p->data[j + 1] = tmp;
			}
		}
	}
}

3.test.c

测试通讯录的模块

#include"contact.h"
void menu()
{
	printf("********1.add       2.del********\n");
	printf("********3.search    4.modify*****\n");
	printf("********5.sort      6.print******\n");
	printf("********0.ex*******************\n");
}
enum day//使用枚举 运行后更加简单明了
{
	ex,//从0开始
	add,
	del,
	search,
	modify,
	sort,
	print
};
int main()
{
	contact  con;
	init(&con);
	int input = 0;
	do
	{
		menu();
		printf("请输入数字:>");
		scanf("%d", &input);
		switch (input)
		{
		case add:
			addcontact(&con);
			break;
		case del:
			delcontact(&con);
			break;
		case search:
			searchcontact(&con);//虽然查找不需要改变结构体本身的内容 但为了提高效率 依旧使用取地址
			break;
		case modify:
			modifycontact(&con);
			break;
		case sort:
			sortcontact(&con);
			break;
		case print:
			printcontact(&con);//跟上面的原因相同 为了加快进行
			break;
		case ex:
			printf("结束");
			break;

		default :
			printf("输入错误 重新输入");
			break;
		}
	} while (input);
	return 0;
}

二、动态内存通讯录

1.contact.h

#define _CRT_SECURE_NO_WARNINGS
#define      cap 3//动态内存空间的初始容量
#define   addcap 2//增大的容量
#include
#include
#include
typedef struct people
{
	char name[20];
	int age;
	char sex[20];
	char tele[20];
	char addr[20];
}pop;
typedef struct contact
{
	pop* data;//指向动态内存空间 用来存放联系人信息
	int sz;//当前记录的个数
	int capity;//动态内存的容量
}contact;
void init(contact* p);
void addcontact(contact* p);
void delcontact(contact* p);
void searchcontact(const contact* p);//这里我们只是寻找数据 不修改 用const修饰结构体本身内容不能被修改 起到保护数据的作用
void modifycontact(contact* p);
void printcontact(contact* p);
void sortcontact(contact* p);
void destory(contact* p);

2.contact.c

相比于静态的 只需将初始化 增加 销毁内存

#include"contact.h"
void init(contact* p)
{
	p->sz = 0;
	 p->data= (pop*)malloc(sizeof(pop));//将结构体中的指针指向动态空间
	p->capity = cap;//cap代表开辟动态内存空间的个数3
}
void addcontact(contact* p)//增加通讯录成员
{
	if (p->sz ==p->capity )//空间已满 要扩容
	{
		pop* ptr = (pop*)realloc(p->data,(p->capity + addcap) * sizeof(pop));//addcap代表增大2个容量
		if (ptr != NULL)
		{
			p->data = ptr;
			p->capity = p->capity + addcap;//将容量扩大到5 str不需要销毁 它并没有开辟动态空间
			printf("扩容成功\n");
		}
	}
	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");
}
int find(contact* p, char name[])
{
	int i = 0;
	for (i = 0; i < p->sz; i++)
	{
		if (strcmp(name, p->data[i].name) == 0)
		{
			return i;
		}
	}
	return -1;
}
void delcontact(contact* p)//删除通讯录成员
{
	if (p->sz == 0)
	{
		printf("没有数据可以删除\n");
		return;
	}
	char name[20];
	printf("请删除输入名字:>");
	scanf("%s", name);
	int ret = find(p, name);
	if (ret == -1)
	{
		printf("没找到\n");
		return;
	}
	else
	{
		int i = 0;
		for (i = 0; i < p->sz - 1; i++)//数据到达倒数第二个就会把倒数第一个数传过来
		{
			p->data[i] = p->data[i + 1];
		}
		p->sz--;//一共有两个倒数第一个的数的值 故删去最后一个数
	}
}
void searchcontact(const contact* p)//查找通讯录成员
{
	char name[20];
	printf("输入要查找的名字:>");
	scanf("%s", name);
	int ret = find(p, name);
	if (ret == -1)
	{
		printf("没找到\n");
		return;
	}
	else
	{
		printf("%20s\t %5s\t %5s\t %20s\t %20s\n", "名字", "年龄", "性别", "电话", "地址");
		printf("%20s\t", p->data[ret].name);
		printf("%5d\t", p->data[ret].age);
		printf("%5s\t", p->data[ret].sex);
		printf("%20s\t", p->data[ret].tele);
		printf("%20s\n", p->data[ret].addr);
	}
}
void modifycontact(contact* p)//修改通讯录成员
{
	char name[20];
	printf("输入名字:>");
	scanf("%s", name);
	int ret = find(p, name);
	if (ret == -1)
	{
		printf("没找到该成员\n");
	}
	else
	{
		printf("请输修改入名字:>");
		scanf("%s", p->data[ret].name);
		printf("请输入修改年龄:>");
		scanf("%d", &p->data[ret].age);
		printf("请输入修改性别:>");
		scanf("%s", p->data[ret].sex);
		printf("请输入修改电话:>");
		scanf("%s", p->data[ret].tele);
		printf("请输入修改地址:>");
		scanf("%s", p->data[ret].addr);
	}
}
void printcontact(contact* p)//输出所有成员
{
	int i = 0;
	printf("%20s\t %5s\t %5s\t %20s\t %20s\n", "名字", "年龄", "性别", "电话", "地址");
	for (i = 0; i < p->sz; i++)
	{
		printf("%20s\t", p->data[i].name);
		printf("%5d\t", p->data[i].age);
		printf("%5s\t", p->data[i].sex);
		printf("%20s\t", p->data[i].tele);
		printf("%20s\n", p->data[i].addr);
	}
}
void sortcontact(contact* p)//将结构体成员排序
{
	int i = 0;
	int j = 0;
	for (i = 0; i < p->sz - 1; i++)
	{
		for (j = 0; j < p->sz - 1 - i; j++)
		{
			if (strcmp(p->data[j].name, p->data[j + 1].name) > 0)
			{
				struct people tmp = p->data[j];
				p->data[j] = p->data[j + 1];
				p->data[j + 1] = tmp;
			}
		}
	}
}
void destory(contact* p)
{
	free(p->data);
	p->data = NULL;
	p->capity = 0;
	p->sz = 0;
}

3. test.c

不要忘记销毁内存

#include"contact.h"
void menu()
{
	printf("********1.add       2.del********\n");
	printf("********3.search    4.modify*****\n");
	printf("********5.sort      6.print******\n");
	printf("********0.ex*******************\n");
}
enum day
{
	ex,
	add,
	del,
	search,
	modify,
	sort,
	print
};
int main()
{
	contact  con;
	init(&con);
	int input = 0;
	do
	{
		menu();
		printf("请输入数字:>");
		scanf("%d", &input);
		switch (input)
		{
		case add:
			addcontact(&con);
			break;
		case del:
			delcontact(&con);
			break;
		case search:
			searchcontact(&con);//虽然查找不需要改变结构体本身的内容 但为了提高效率 依旧使用取地址
			break;
		case modify:
			modifycontact(&con);
			break;
		case sort:
			sortcontact(&con);
			break;
		case print:
			printcontact(&con);
			break;
		case ex:
			printf("结束");
			destory(&con);//销毁内存
			break;

		default:
			printf("输入错误 重新输入");
			break;
		}
	} while (input);
	return 0;
}

你可能感兴趣的:(c语言,c语言,开发语言)