动态通讯录
上一次分享了静态扩容通讯录的内容,但是,容量是固定的,若想实现可无限增容的通讯录,也得用到malloc,realloc等动态内存开辟的函数进行改造
要想实现静态通讯录实现动态化
就要将源码的初始化函数和添加联系人函数进行改造,使其扩容增加上限
相对于静态通讯录的一些修改
静态通讯录参考于此:http://t.csdn.cn/zZO7w
增加新的宏定义
#define DEFAULT_sz 3
//初始化初始存储联系人信息数为3
#define INC_SZ 2
//初始化扩容量为2
首先对信息量和信息量计数数据进行改造
typedef struct contact
{
int sz;
//通讯录存入信息量
pd *data;
//通讯录存入信息数据数组
int capacity;
}contact;
相对于静态通讯录,添加了capacity这个变量计储量
对初始化函数进行改造
void initialization(contact* c)
{ //初始化数组的大小为3个联系人空间
//每次可扩容2个
c->data = (pd*)malloc(DEFAULT_sz * sizeof(pd));
if (c->data == NULL)
{
printf("通讯录初始化失败:%s\n", strerror(errno));
return;
}
c->sz = 0;
c->capacity = DEFAULT_sz;
}
通过malloc来开辟内存来存储联系人信息并且单独分装应该一个函数专门来做增加扩容操作
添加联系人函数的改造
int CheckCapacity(contact*c)
{
if (c->sz == c->capacity)
{
pd* ptr = (pd*)realloc(c->data, (c->capacity + INC_SZ) * sizeof(pd));
if (ptr == NULL)
{
printf("CheckCapacity:%s\n", strerror(errno));
return 0;
}
else
{
c->data = ptr;
c->capacity += INC_SZ;
printf("扩容成功,当前容量为%d\n", c->capacity);
return 1;
}
}
}
void Add(contact* c)//增加联系人的个数
{
if (CheckCapacity(c) ==0)
{
printf("空间不够,扩容失败\n");
return;
}
else
{
printf("请输入姓名\n");
scanf("%s", c->data[c->sz].name);
printf("请输入性别\n");
scanf("%s", c->data[c->sz].sex);
printf("请输入年龄\n");
scanf("%d", &(c->data[c->sz].age));
printf("请输入电话\n");
scanf("%s", c->data[c->sz].tel);
printf("请输入住址\n");
scanf("%s", c->data[c->sz].addr);
c->sz++;//输入完联系人数目+1
printf("添加成功\n");
}
}
通过realloc来调整内存空间大小,联系人数量和存储量相同时候,扩容+2
动态内存内存释放销毁内容
//对通讯录动态开辟内存的释放
void DestroyContact(Contact* c)
{
free(pc->data);
pc->data = NULL;
pc->capacity = 0;
pc->sz = 0;
printf("释放内存......\n");
}
动态通讯录完整代码
contact.h
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<errno.h>
#define MAX 100
#define NAME 20
#define SEX 5
#define TEL 20
#define ADDR 30
#define DEFAULT_sz 3
#define INC_SZ 2
//个人信息的存储
typedef struct Peopleidfaction
{
char name[NAME];
int age;
char sex[SEX];
char tel[TEL];
char addr[ADDR];
}pd;
//通讯录的内容大小限制和数据数
typedef struct contact
{
int sz;
//通讯录存入信息量
pd *data;
//通讯录存入信息数据数组
int capacity;
}contact;
//初始化数组
void initialization(contact *c);
//添加联系人的函数声明
void Add(contact* c);
//删除联系人的函数声明
void DestroyContact(contact* c);
//销毁通讯录
void del(contact* c);
//查找该联系人的判断
static int Find_by_name(char name[], const contact* c);
//查询联系人的信息
void Search(const contact*c);
//修改联系人信息
void Modify(contact* c);
//排序联系人信息
void Qsort(contact* c);
//清空所有联系人
void Clear(contact* c);
//显示所有联系人
void Show(const contact* c);
contact.c
#define _CRT_SECURE_NO_DEPRECATE 1
#include"contact.h"
void initialization(contact* c)
{ //初始化数组的大小为3个联系人空间
//每次可扩容2个
c->data = (pd*)malloc(DEFAULT_sz * sizeof(pd));
if (c->data == NULL)
{
printf("通讯录初始化失败:%s\n", strerror(errno));
return;
}
c->sz = 0;
c->capacity = DEFAULT_sz;
}
//查询联系人姓名单独分装一个函数
static int Find_by_name(char name[], const contact* c)
{
//将输入的name与通讯录中的name进行比对,找到返回位置
//找不到返回-1
for (int i = 0; i < c->sz; i++)
{
if (strcmp(c->data[i].name, name) == 0)
{
return i;
}
}
return -1;
}
int CheckCapacity(contact* c)
{
if (c->sz == c->capacity)
{
pd* ptr = (pd*)realloc(c->data, (c->capacity + INC_SZ) * sizeof(pd));
if (ptr == NULL)
{
printf("CheckCapacity:%s\n", strerror(errno));
return 0;
}
else
{
c->data = ptr;
c->capacity += INC_SZ;
printf("扩容成功,当前容量为%d\n", c->capacity);
return 1;
}
}
}
void Add(contact* c)//增加联系人的个数
{
if (CheckCapacity(c) == 0)
{
printf("空间不够,扩容失败\n");
return;
}
else
{
printf("请输入姓名\n");
scanf("%s", c->data[c->sz].name);
printf("请输入性别\n");
scanf("%s", c->data[c->sz].sex);
printf("请输入年龄\n");
scanf("%d", &(c->data[c->sz].age));
printf("请输入电话\n");
scanf("%s", c->data[c->sz].tel);
printf("请输入住址\n");
scanf("%s", c->data[c->sz].addr);
c->sz++;//输入完联系人数目+1
printf("添加成功\n");
}
}
//删除联系人
void del(contact* c)
{
char name[NAME] = { 0 };
//创建一个存名字的数组
if (c->sz == 0)
{
printf("通讯录无联系人,退出操作\n");
return;
}
printf("请输入你要删除的联系人的姓名:");
scanf("%s", name);
int ret = Find_by_name(name, c);
if (ret == -1)
{
printf("对不起,该联系人不存在");
return;
}
int i = 0;
//删除-删除ret位置上的数据
for (i = ret; i < c->sz - 1; i++)
{
c->data[i] = c->data[i + 1];
}
c->sz--;
printf("删除成功\n");
}
//查询联系人
void Search(const contact* c)
{
char name[NAME] = { 0 };
printf("请输入要查找人的名字:>");
scanf("%s", name);
//向通讯录查询联系人姓名
int ret = Find_by_name(name, c);
if (-1 == ret)
{
printf("对不起,你所搜索的联系人不存在\n");
return;
}
//姓名 年龄 性别 电话 地址
//zhangsan 20 男 123456 北京
printf("%-10s %-5s %-5s %-12s %-30s\n", "姓名", "年龄", "性别", "电话", "地址");
printf("%-10s %-5d %-5s %-12s %-30s\n",
c->data[ret].name,
c->data[ret].age,
c->data[ret].sex,
c->data[ret].tel,
c->data[ret].addr);
}
//修改联系人信息
void Modify(contact* c)
{
char name[NAME] = { 0 };
printf("请输入你要修改的联系人姓名");
scanf("%s", name);
int ret = Find_by_name(name, c);
if (-1 == ret)
{
printf("对不起,该联系人不存在");
return;
}
printf("请输入姓名\n");
scanf("%s", c->data[c->sz].name);
printf("请输入性别\n");
scanf("%s", c->data[c->sz].sex);
printf("请输入年龄\n");
scanf("%d", &(c->data[c->sz].age));
printf("请输入电话\n");
scanf("%s", c->data[c->sz].tel);
printf("请输入住址\n");
scanf("%s", c->data[c->sz].addr);
printf("修改成功\n");
}
//展现通讯录表
void Show(const contact* c)
{
//格式化
//姓名 年龄 性别 电话 地址
//李四 20 男 133 上海
printf("%-10s %-5s %-5s %-12s %-30s\n", "姓名", "年龄", "性别", "电话", "地址");
for (int i = 0; i < c->sz; i++)
{
printf("%-10s %-5d %-5s %-12s %-30s\n",
c->data[i].name,
c->data[i].age,
c->data[i].sex,
c->data[i].tel,
c->data[i].addr);
}
}
int cmp_by_name(const void* p1, const void* p2)
{
return strcmp(((pd*)p1)->name, ((pd*)p2)->name);
}
//快排函数
void Qsort(contact* c)
{
int sz = sizeof(c->data) / sizeof(c->data[0]);
qsort(c->data, c->sz, sizeof(pd), cmp_by_name);
printf("排序成功!\n");
}
void Clear(contact* c)
{
initialization(c);
printf("清除成功!\n");
}
void DestroyContact(contact* c)
{
free(c->data);
c->data = NULL;
c->capacity = 0;
c->sz = 0;
printf("释放内存......\n");
}
test.c
#include"contact.h"
void menu()
{
printf("****************************************\n");
printf("******* 1. ADD 2. DEL ********\n");
printf("******* 3. SEARCH 4. MODIFY ********\n");
printf("******* 5. SHOW 6. CLEAR ********\n");
printf("******* 7. QSORT 0. EXIT ********\n");
printf("****************************************\n");
}
enum funtion
{
EXIT,
ADD,
DEL,
SEARCH,
MODIFY,
SHOW,
CLEAR,
QSORT
};
int main()
{
int input = 0;
contact con;
initialization(&con);
do
{
menu();//打印菜单界面
scanf("%d", &input);//输入选择
switch (input)
{
case ADD:
//增加联系人的功能
Add(&con);
break;
case DEL:
//删除联系人的功能
del(&con);
break;
case SEARCH:
//查找联系人的功能
Search(&con);
break;
case MODIFY:
//修改联系人的功能
Modify(&con);
break;
case SHOW:
//显示联系人的功能
Show(&con);
break;
case CLEAR:
//清除所有联系人的功能
Clear(&con);
break;
case QSORT:
//排序联系人的功能,可以通过初始化来操作
Qsort(&con);
break;
case EXIT:
//退出程序
printf("退出程序\n");
DestroyContact(&con);
break;
default:
printf("选择错误\n");
break;
}
} while (input);
return 0;
}
OK,今天的动态通讯录内容便分析于此!!