前几天刚刚写了静态的通讯录,是采用的数组的形式来写的,那种通讯录存在比较大的弊端。一方面,静态的通讯录只有固定的大小,如果用完就不能再存了。另一方面呢,如果开辟的内存比较大,但是存的联系人比较少的话,就造成了很大的浪费。今天用动态内存开辟空间,可以完美解决这两个问题。主要利用malloc()
函数和realloc()
函数,那么我们先开辟一个小内存,然后存一两个联系人,内存不够的话再开辟,这就实现了存几个联系人就开辟多大空间,对于空间比较节省。
鉴于上次的通讯录我介绍的比较详细,我这次的介绍简单一点。
头文件
pmessage.h
#ifndef __Message_H__
#define __Message_H__
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
#include<string.h>
#include<ctype.h>
#define MAX 1000 //最大1000位联系人
#define NAME_MAX 20 //名字最长
#define GENDER_MAX 5 //性别
#define ADDR_MAX 30 //地址
#define TELE_MAX 12 //电话('\0')
#define INIT_NUM 5 //初始化通讯录容量
#define INC_NUM 3 //每次通讯录扩容大小
typedef struct Person{
char name[NAME_MAX];
char gender[GENDER_MAX];
char address[ADDR_MAX];
char tele[TELE_MAX];
int age;
}Person;
typedef struct Message
{
Person *arr;
int count;
int capacity;
}message;
void AddMessage(message *mess); //增加联系人
void CheckCapacity(message *pcon); //判断容量是否满
void ShowMessage(const message *mess); //展示所有已存的联系人
int FindPosition(message *mess); //查找指定联系人所在位置
int DelMessage(message *mess); //删除某个联系人
int FindMesaage(message *mess); //查找某个联系人。
int ModifyMessage(message *mess); //修改联系人
void ClearMessage(message *mess); //清除所有的联系人
void SortMessage(message *mess); //对联系人分类(姓名比较)
void InitMessage(message *mess); //初始化通讯录
#endif
测试函数
ptest.c
- 这个函数比较简单,主要就用了一个枚举
- 接下来就是菜单函数,也没有什么可说的了。
#include"pmessage.h"
enum {
EXIT, //0
ADD, //1
DEL, //2
SEARCH, //3
MODIFY, //4
SHOW, //5
SORT, //6
CLEAR, //7
};
void meau()
{
printf(" *********************************************\n");
printf(" *********************************************\n");
printf(" ###############My address book###############\n");
printf(" * 1-add 2-del 3-search *\n");
printf(" * 4-modify 5-show 6-Sort *\n");
printf(" * 0-Exit 7-clear *\n");
printf(" *********************************************\n");
printf(" *********************************************\n");
}
void test()
{
int input = 0;
message my_con;
InitMessage(&my_con);
do
{
meau();
printf("请选择:");
scanf_s("%d", &input);
switch (input)
{
case ADD://添加
AddMessage(&my_con);
break;
case SHOW://显示
ShowMessage(&my_con);
break;
case DEL://删除
DelMessage(&my_con);
break;
case SEARCH://查找
FindMessage(&my_con);
break;
case MODIFY://修改
ModifyMessage(&my_con);
break;
case SORT://排序
SortMessage(&my_con);
break;
case CLEAR://清除
ClearMessage(&my_con);
break;
case EXIT://退出
exit(0);
break;
default:
printf("输入有误");
break;
}
} while (input);
}
int main(void)
{
test();
return 0;
}
功能函数
这里的每个函数我一个一个的介绍。
- 通讯录初始化函数
void InitMessage(message *pcon)
{
pcon->count = 0;
pcon->arr = (Person *)malloc(sizeof(Person)*INIT_NUM);
memset(pcon->arr, 0, INIT_NUM*sizeof(Person));
pcon->capacity = INIT_NUM;
}
- 判断容量是否已满函数
如果容量不够就继续开辟
void CheckCapacity(message *pcon) //判断容量是否满
{
if (pcon->count < pcon->capacity)
{
pcon->arr = (Person *)realloc(pcon->arr, sizeof(Person)*INC_NUM);
pcon->capacity = pcon->capacity + INC_NUM;
}
}
- 增加联系人
void AddMessage(message *pcon) //添加
{
printf("请输入名字>");
scanf("%s", pcon->arr[pcon->count].name);
printf("请输入性别>");
scanf("%s", pcon->arr[pcon->count].gender);
printf("请输入年龄>");
scanf("%d", &(pcon->arr[pcon->count].age));
printf("请输入电话>");
scanf("%s", pcon->arr[pcon->count].tele);
printf("请输入住址>");
scanf("%s", pcon->arr[pcon->count].address);
pcon->count++;
}
- 显示所有联系人
void ShowMessage(message *pcon) //显示联系人
{
int i = 0;
printf("%15s\t%5s\t%5s\t%15s\t%15s\n", "姓名", "年龄", "性别", "地址", "电话");
for (i = 0; i < pcon->count; i++)
{
printf("%15s\t%5d\t%5s\t%15s\t%15s\n",
pcon->arr[i].name,
pcon->arr[i].age,
pcon->arr[i].gender,
pcon->arr[i].address,
pcon->arr[i].tele);
}
}
- 查找联系人所在的位置,为后面的函数服务
int FindPosition(message *pcon)//查找指定联系人所在位置
{
int i = 0;
char name[NAME_MAX];
int ret = 0;
printf("请输入名字:");
scanf("%s", name);
for (i = 0; i<pcon->count; i++)
{
ret = strcmp(name, pcon->arr[i].name);
if (ret == 0)
{
return i;
}
}
return -1;
}
- 删除联系人
int DelMessage(message *pcon)//删除指定联系人信息
{
int i = 0;
int ret = 0;
printf("删除联系人\n");
ret = FindPosition(pcon);
if (ret == -1)
{
printf("你要删除的姓名不存在!!!\n");
return -1;
}
else
{
for (i = ret; i<pcon->count - 1; i++)
{
pcon->arr[i] = pcon->arr[i + 1];
}
pcon->count--;
return 0;
}
}
- 修改联系人
int ModifyMessage(message *pcon)//修改指定联系人的信息
{
int ret = 0;
printf("修改联系人信息>");
ret = FindPosition(pcon);
if (ret == -1)
{
printf("你要修改的联系人不存在!!!\n");
return -1;
}
else
{
printf("请输入要修改的数据:\n");
printf("请输入名字>");
scanf("%s", pcon->arr[ret].name);
printf("请输入性别>");
scanf("%s", pcon->arr[ret].gender);
printf("请输入年龄>");
scanf("%d", &(pcon->arr[ret].age));
printf("请输入电话>");
scanf("%s", pcon->arr[ret].tele);
printf("请输入住址>");
scanf("%s", pcon->arr[ret].address);
return 0;
}
}
- 清空所有联系人
void ClearMessage(message *pcon)//清空所有联系人(还原成初始化状态)
{
pcon->count = 0;
pcon->arr = (Person *)malloc(sizeof(Person)*INIT_NUM);
memset(pcon->arr, 0, INIT_NUM*sizeof(Person));
pcon->capacity = INIT_NUM;
}
- 查找某个联系人
int FindMessage(message *pcon)//查找并且输出这个找到的信息。
{
int ret = 0;
ret = FindPosition(pcon);
if (ret == -1)
{
printf("你要查找的名字不存在!!!\n");
return -1;
}
else
{
printf("姓名:%s性别:%s年龄:%d电话:%s地址:%s\n",
pcon->arr[ret].name,
pcon->arr[ret].gender,
pcon->arr[ret].age,
pcon->arr[ret].tele,
pcon->arr[ret].address);
return 0;
}
}
- 联系人排序(姓名)
void SortMessage(message *pcon)//以名字排序所有联系人
{
int i = 0;
int j = 0;
int flag = 0;
printf("以名字进行排序(a-->z)\n");
while (1)
{
flag = 0;
for (j = 0; j < pcon->count - 1; j++)
{
if (strcmp(pcon->arr[j].name, pcon->arr[j + 1].name)>0)
{
Person tmp = pcon->arr[j];
pcon->arr[j] = pcon->arr[j + 1];
pcon->arr[j + 1] = tmp;
flag = 1;
}
}
if (flag == 0)
break;
}
}