【C语言】动态通讯录

2024-03-01 09:05:25 浏览数 (2)

今天来改进一下静态版本的通讯录,让通讯录的内存空间可以随大小变化;

一、测试部分

测试部分的改动不大,主要的改动还是在函数实现的部分和声明部分;

代码语言:javascript复制
			void menu()
			{
				printf("******      1.Add         2.Del     ***********n");
				printf("******      3.Search      4.Modify  ***********n");
				printf("******      5.Show        6.Sort    ***********n");
				printf("******             0.exit           ***********n");
				printf("***********************************************n");
			}
			
			enum Option
			{
				EXIT,
				ADD,
				DEL,
				SEARCH,
				MODIFY,
				SHOW,
				SORT,
			};
			
			int main()
			{
				int input = 0;
				Contact con;
				InitContact(&con);
				do
				{
					menu();
					printf("请选择:n");
					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 SHOW:
						ShowContact(&con);
						break;
					case SORT:
						SortContact(&con);
						break;
					case EXIT:
						DestoryContact(&con);
						printf("退出通讯录n");
						break;
					default:
						printf("输入错误。请重新输入:n");
						break;
					}
				} while (input);
				return 0;
			}

二、 函数的实现部分

函数的实现部分主要改变了:

通讯录初始化的方式,改用malloc开辟空间

添加联系人的方式,当空间容量不够,使用realloc拓展空间

退出通讯录,需要使用free释放空间以及置空;

代码语言:javascript复制
 		//动态版本初始化通讯录
 		void InitContact(Contact* pc)
 		{
 			pc->data = (PeoInfo*)malloc(DEFAULT_SZ * sizeof(PeoInfo));
 			assert(pc->data);
 			pc->sz = 0;
 			pc->Capacity = DEFAULT_SZ;
 		}
 		
 		//查找函数
 		//加static修饰这个函数是为了这个函数只能在这个.c文件内用,出了这个文件就用不了
 		static int FindByName(Contact* pc, char* name)
 		{
 			int i = 0;
 			for (i = 0; i < pc->sz; i  )
 			{
 				//如果找到了就返回这个下标
 				if (strcmp(pc->data[i].name, name) == 0)
 				{
 					return i;
 				}
 			}
 			return -1;
 		}
 		
 		
 		//打印通讯录
 		void ShowContact(Contact* pc)
 		{
 			int i = 0;
 			//打印标题
 			printf("%-10s %-4s %-5s %-12s %-30sn", "姓名", "年龄", "性别", "电话", "地址");
 			for (i = 0; i < pc->sz; i  )
 			{
 				printf("%-10s %-4d %-5s %-12s %-30sn",
 					pc->data[i].name,
 					pc->data[i].age,
 					pc->data[i].sex,
 					pc->data[i].tele,
 					pc->data[i].addr);
 			}
 			printf("n");
 		}
 		
 		
 		//检查Capacity的容量是否满
 		void CheakCapacity(Contact* pc)
 		{
 			if (pc->Capacity == pc->sz)
 			{
 				PeoInfo* ptr = (PeoInfo*)realloc(pc->data, (pc->Capacity   INC_SZ) * sizeof(PeoInfo));
 				assert(ptr);
 		
 				pc->Capacity  = INC_SZ;
 				pc->data = ptr;
 		
 				printf("增容成功!n");
 			}
 		}
 		
 		//增加指定联系人
 		void AddContact(Contact* pc)
 		{
 			CheakCapacity(pc);
 		
 			printf("请输入名字:");
 			scanf("%s", pc->data[pc->sz].name);
 			printf("请输入年龄:");
 			scanf("%d", &(pc->data[pc->sz].age));
 			printf("请输入性别:");
 			scanf("%s", pc->data[pc->sz].sex);
 			printf("请输入电话:");
 			scanf("%s", pc->data[pc->sz].tele);
 			printf("请输入地址:");
 			scanf("%s", pc->data[pc->sz].addr);
 		
 			//添加完sz的长度  
 			pc->sz  ;
 			printf("添加成功n");
 		}
 		
 		
 		//删除指定联系人
 		void DelContact(Contact* pc)
 		{
 			//通讯录为空
 			if (pc->sz == 0)
 			{
 				printf("通讯录为空,无法删除n");
 				return;
 			}
 			//不为空,删除
 			char name[MAX_NAME];
 			printf("请输入名字:");
 			scanf("%s", &name);
 			//一个查找函数,因为查找功能重复,所以写一个查找函数更好
 			int pos = FindByName(pc, name);
 			if (pos == -1)
 			{
 				printf("要删除的不存在n");
 				return;
 			}
 			int i = 0;
 			//将后面的数据往前挪
 			for (i = pos; i < pc->sz; i  )
 			{
 				pc->data[i] = pc->data[i   1];
 			}
 			//挪完后有效数据的长度--
 			pc->sz--;
 			printf("删除成功n");
 		}
 		
 		
 		//在通讯录查找指定的人
 		void SearchContact(Contact* pc)
 		{
 			printf("请输入要查找的人的名字:");
 			char name[MAX_NAME];
 			scanf("%s", &name);
 			int pos = FindByName(pc, name);
 			if (pos == -1)
 			{
 				printf("要查找的人不存在n");
 				return;
 			}
 			printf("查找成功!nn");
 			printf("%-10s %-4s %-5s %-12s %-30sn", "姓名", "年龄", "性别", "电话", "地址");
 			//找到了打印数据
 			printf("%-10s %-4d %-5s %-12s %-30sn",
 				pc->data[pos].name,
 				pc->data[pos].age,
 				pc->data[pos].sex,
 				pc->data[pos].tele,
 				pc->data[pos].addr);
 			printf("n");
 		}
 		
 		
 		//修改通讯录的数据
 		void ModifyContact(Contact* pc)
 		{
 			printf("请输入需要修改的人的名字:");
 			char name[MAX_NAME];
 			scanf("%s", &name);
 			int pos = FindByName(pc, name);
 			if (pos == -1)
 			{
 				printf("不存在此人n");
 				return;
 			}
 			//找到了就修改pos下标的数据
 			printf("请重新输入TA的数据n");
 			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].tele);
 			printf("请输入地址:");
 			scanf("%s", pc->data[pos].addr);
 			printf("修改成功n");
 		}
 		
 		
 		//按照名字排序
 		int cmp_by_name(void* e1, void* e2)
 		{
 			//强转成PeoInfo*类型
 			return strcmp(((PeoInfo*)e1)->name, ((PeoInfo*)e2)->name);
 		}
 		
 		void SortContact(Contact* pc)
 		{
 			printf("按照名字排列:n");
 			qsort(pc->data, pc->sz, sizeof(PeoInfo), cmp_by_name);
 			printf("排序成功nn");
 		}
 		
 		
 		//销毁通讯录
 		void DestoryContact(Contact* pc)
 		{
 			free(pc->data);
 			pc->data = NULL;
 			pc->Capacity = 0;
 			pc->sz = 0;
 			printf("释放内存n");
 		}

三、函数的声明部分

代码语言:javascript复制
			#include <stdio.h>
			#include <string.h>
			#include <stdlib.h>
			#include <assert.h>
			
			#define MAX_NAME 20
			#define MAX_SEX 5
			#define MAX_TELE 12
			#define MAX_ADDR 30
			
			//定义开始默认通讯录开辟空间的大小
			#define DEFAULT_SZ 3
			//定义每次
			#define INC_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;//data指向了存放数据的空间
				int sz;//记录通讯录中有效信息的个数
				int Capacity;//通讯录当前的容量
			}Contact;
			
			
			//初始化通讯录
			void InitContact(Contact* pc);
			
			//打印通讯录
			void ShowContact(Contact* pc);
			
			//增加指定联系人
			void AddContact(Contact* pc);
			
			//删除指定联系人
			void DelContact(Contact* pc);
			
			//在通讯录查找指定的人
			void SearchContact(Contact* pc);
			
			//修改通讯录的数据
			void ModifyContact(Contact* pc);
			
			//排序通讯录
			void SortContact(Contact* pc);
			
			//销毁通讯录
			void DestoryContact(Contact *pc);

0 人点赞