动态内存增长的通讯录
实现一个通讯录:
通讯录可以用来存储个人的信息,每个人的信息包括:
姓名、性别、年龄、电话、住址。
姓名、性别、年龄、电话、住址。
实现的功能:
1. 添加联系人信息
2. 删除指定联系人信息
3. 查找指定联系人信息
4. 修改指定联系人信息
5. 显示所有联系人信息
6. 清空所有联系人
7. 以名字排序所有联系人
2. 删除指定联系人信息
3. 查找指定联系人信息
4. 修改指定联系人信息
5. 显示所有联系人信息
6. 清空所有联系人
7. 以名字排序所有联系人
并且这个通讯录要用来持续使用,所以每次程序结束时要保存数据到文件中去,因此下次运行时就要
从文件中来读取 。
同时,为了节省空间大小,程序中定义的联系人的个数,应该用动态增长的方式来开辟内存,不会因此而
导致
多余的内存浪费 。
下面是代码的实现
~~~~~~~~~~定义的头文件——函数的声明、宏的定义~~~~~~~~~~
<span style="font-size:18px;">#pragma once//在头文件中加入这条指令,可以保证编译头文件一次
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_NAME 20//联系人姓名的大小
#define MAX_SEX 5
#define MAX_PHONE 12//联系人电话的长度
#define MAX_ADRESS 30//联系人地址的长度
#define START 1//动态开辟内存,初始化的长度
#define ADD 1//动态增加的长度
#define FILENAME "book.txt"//定义的存储的文件名
//定义的联系人的结构体
typedef struct Contacts
{
char name[MAX_NAME];
char sex[MAX_SEX];
int age;
char phone[MAX_PHONE];
char adress[MAX_ADRESS];
}Con,*pCon;
//定义的的通讯录的结构体
typedef struct tphonebook
{
pCon con;//联系人信息
size_t lengh;//联系人个数
size_t width;//为联系人开辟的空间大小
}tbook,*ptbook;
//初始化通讯录
void Initphonebook(ptbook my_book);
//添加联系人
void Insert(ptbook my_book);
//删除联系人
void Delete(ptbook my_book);
//查找联系人
void Search(ptbook my_book);
//修改联系人
void Update(ptbook my_book);
//显示联系人
void Print(ptbook my_book);
//清空联系人
void Empty(ptbook my_book);
//将联系人名按照字排序
void Sort_name(ptbook my_book);
//从文件中读取数据
void Read(ptbook my_book);
//将数据写入到文件
void Save(ptbook my_book);
//释放动态开辟的空间
void Free(ptbook my_book);
</span>
~~~~~~~~~~源文件——函数的实现~~~~~~~~~~
#define _CRT_SECURE_NO_WARNINGS
#include"xiaodong.h"//头文件引入写的
//修改联系人信息时,使用
void menu2()
{
printf("所要修改的信息:\n");
printf("1.姓名; 2.性别\n");
printf("3.年龄; 4.电话\n");
printf("5.地址; 0.exit\n");
}
//初始化一个通讯录
void Initphonebook(ptbook my_book)
{
my_book->con = (pCon)calloc(START,sizeof(Con));
//用calloc开辟空间的话,会将开辟的空间初始化为全0 ,malloc则不会初始化
if(my_book->con ==NULL)
{
printf("初始化失败\n");
}
else
{
my_book->lengh = 0;
my_book->width = START;//将定义的初始化长度 给 为联系人开辟的空间大小
}
}
//判断通讯录的联系人空间是否够用,不够的话,为它添加空间
void If_space(ptbook my_book)
{
pCon temp= NULL;
if(my_book->lengh >= my_book->width)
{
temp = (pCon)realloc(my_book->con,(my_book->width+ADD)*sizeof(Con));//动态内存开辟,可以为已开辟的空间进行操作,添加或减小
//不能讲realloc开辟的空间的首地址直接给原来的地址 ,因为一旦开辟失败,就会将原本的内容丢掉
if(temp == NULL)
{
printf("该电话本联系人已达到最大,不能继续添加。\n");
}
else
{
my_book->con = temp;
my_book->width +=ADD;//联系人空间加上增加的空间
}
}
}
//添加联系人信息
void Insert(ptbook my_book)
{
If_space(my_book);//判断是否要为联系人增加空间
printf("请输入要添加的联系人的信息:>\n");
printf("name:>");
scanf("%s",(my_book->con + my_book->lengh)->name);
printf("sex:>");
scanf("%s",(my_book->con + my_book->lengh)->sex);
printf("age:>");
scanf("%d",&(my_book->con + my_book->lengh)->age);
printf("phone:>");
scanf("%s",(my_book->con + my_book->lengh)->phone);
printf("adress:>");
scanf("%s",(my_book->con + my_book->lengh)->adress);
my_book->lengh++;
}
//删除指定联系人信息
void Delete(ptbook my_book)
{
char Name[10]={0};
size_t i = 0;
size_t m = 0;
if(!my_book->lengh)
{
printf("该电话本为空,未保存联系人.\n");
}
else
{
printf("请输入要删除的联系人姓名:>");
scanf("%s",Name);
for(i =0 ;i< (my_book->lengh);i++)
{
size_t j =0;
m = (my_book->lengh);
if(!strcmp(Name,(my_book->con+i)->name))
{
int size_t = 0;
for(j = i;j< my_book->lengh-1;j++)
{
*(my_book->con+j) = *(my_book->con+j+1);
}
printf("删除成功\n");
my_book->lengh--;
break;
}
}
if(i == m)
printf("电话本里没有该联系人。\n");
}
}
//查找指定联系人信息
void Search(ptbook my_book)
{
size_t i = 0;
char Name[10]={0};
if(!my_book->lengh)
{
printf("该电话本为空,未保存联系人.\n");
}
else
{
printf("请输入要查找的联系人的姓名:>");
scanf("%s",Name);
for(i= 0;i<(my_book->lengh);i++)
{
if(!strcmp(Name,(my_book->con+i)->name))
{
printf("找到了,该联系人在通讯录中的信息是:\n");
printf("编号 姓名 性别 年龄 电话 住址\n");
printf("%d %s %s %d %s %s\n",i+1
,(my_book->con+i)->name
,(my_book->con+i)->sex
,(my_book->con+i)->age
,(my_book->con+i)->phone
,(my_book->con+i)->adress);
break;
}
}
if(i == (my_book->lengh))
printf("电话本里没有该联系人。\n");
}
}
//修改指定联系人信息
void Update(ptbook my_book)
{
size_t i= 0;
int input=0;
char Name[10]={0};
if(!my_book->lengh)
{
printf("该电话本为空,未保存联系人.\n");
}
else
{
printf("请输入要修改的联系人姓名:>");
scanf("%s",Name);
for(i= 0 ;i<(my_book->lengh);i++)
{
if(!strcmp(Name,(my_book->con+i)->name))
{
menu2();
printf("请选择:>");
scanf("%d",&input);
switch(input)
{
case 1:
printf("修改后的内容为:");
scanf("%s",(my_book->con+i)->name);
break;
case 2:
printf("修改后的内容为:");
scanf("%s",(my_book->con+i)->sex);
break;
case 3:
printf("修改后的内容为:");
scanf("%d",&(my_book->con+i)->age);
break;
case 4:
printf("修改后的内容为:");
scanf("%s",(my_book->con+i)->phone);
break;
case 5:
printf("修改后的内容为:");
scanf("%s",(my_book->con+i)->adress);
break;
case 0:
break;
default:
break;
}
break;
}
}
if(i == (my_book->lengh))
printf("电话本里没有该联系人。\n");
}
}
//显示所有联系人信息
void Print(ptbook my_book)
{
size_t i = 0;
if(!my_book->lengh)
{
printf("该电话本为空,未保存联系人.\n");
}
else
{
printf("编号 姓名 性别 年龄 电话 住址\n");
for(i =0 ;i<(my_book->lengh);i++)
{
printf("%d %s %s %d %s %s\n",i+1
,(my_book->con+i)->name
,(my_book->con+i)->sex
,(my_book->con+i)->age
,(my_book->con+i)->phone
,(my_book->con+i)->adress);
}
printf("\n");
}
}
//清空所有联系人
void Empty(ptbook my_book)
{
if(!my_book->lengh)
{
;
}
else
{
memset(my_book->con,0,my_book->lengh*sizeof(Con));//memset内存设置函数,将一段空间设置一个值
my_book->lengh = 0;
}
printf("清空成功\n");
}
//以名字排序所有联系人
void Sort_name(ptbook my_book)
{
int i =0 ;
int j =0 ;
int sz=my_book->lengh-1;
if(!my_book->lengh)
{
printf("该电话本为空,未保存联系人.\n");
}
else
{
for(i = 0;i<sz;i++)
{
for(j =0 ;j<sz-i;j++)
{
if(strcmp((my_book->con+j)->name,(my_book->con+j+1)->name)>0)
{
Con temp = *(my_book->con+j);
*(my_book->con+j)= *(my_book->con+j+1);
*(my_book->con+j+1)= temp;
}
}
}
printf("排序成功\n");
}
}
void Read(ptbook my_book)
{
Con book;
FILE *pf =fopen(FILENAME,"r");
if(pf == NULL)
{
perror("error:");
Free(my_book);
exit(EXIT_FAILURE);
}
while(fread(&book,sizeof(Con),1,pf))//从文件中读取数据,,直到读取的为空
{
If_space (my_book);
my_book->con[my_book->lengh++] = book;
}
fclose(pf);//记着关闭文件
}
void Save(ptbook my_book)
{
size_t i = 0;
FILE *pf =fopen(FILENAME,"w");
if(pf == NULL)
{
perror("error:");
Free(my_book);
exit(EXIT_FAILURE);
}
for(i = 0;i<my_book->lengh;i++)
{
fwrite(my_book->con+i,sizeof(Con),1,pf);//从文件中读取一个联系人信息,放到通讯录的联系人列表;
}
fclose(pf);
}
//释放动态开辟的空间
void Free(ptbook my_book)
{
if(my_book->con!=NULL)
{
free(my_book->con);
my_book->con=NULL;
}
}
~~~~~~~~~~测试函数——主函数~~~~~~~~~~
#define _CRT_SECURE_NO_WARNINGS
#include"xiaodong.h"
void menu1()
{
printf(" 通讯录 \n\n");
printf("1. 添加联系人信息 2. 删除指定联系人信息\n");
printf("3. 查找指定联系人信息 4. 修改指定联系人信息\n");
printf("5. 显示所有联系人信息 6. 清空所有联系人\n");
printf("7. 以名字排序所有联系人 0. exit(0)\n\n");
}
int main()
{
int input = 1;
tbook My_book;
void (*fun[8])(ptbook)={0,Insert,Delete,Search,Update,Print,Empty,Sort_name};//转移表
Initphonebook(&My_book);
Read(&My_book);
while(input)
{
menu1();
printf("请输入要选择的功能:>");
scanf("%d",&input);
if(input)
(*fun[input])(&My_book);
}
Save(&My_book);
free(My_book.con);//一定要记得回收
system("pause");
return 0;
}