//需要创建三个文档,两个源文件,一个头文件
//第一个测试源文件为
#include "contast.h"
void menu()
{
printf("************************************\n");
printf("****** 1.ADD 2.DEL *********\n");
printf("****** 3.RESEARCH 4.MODIFY ******\n");
printf("****** 5.SHOW 0.EXIT *******\n");
printf("************************************\n");
}
void Init_Contact(struct contact* p)//初始化通信录里的信息
{
p->size=0;
p->capacity=3;
p->data=(struct people*)malloc(p->capacity*(sizeof(struct people)));
Load_catact(p);//进行将之前通信录数据的导入
}
int main()
{
int input=0;
struct contact p1;
Init_Contact(&p1);
do
{
menu();
printf("请输入你的选择:");
scanf("%d",&input);
switch(input)
{
case ADD://ADD DEL等利用枚举可以增加文档的可读性
ADD_contact(&p1);
break;
case DEL:
DEL_contact(&p1);
break;
case RESEARCH:
RESEARCH_contact(&p1);
break;
case MODIFY:
MODIFY_contact(&p1);
break;
case SHOW:
SHOW_contact(&p1);
break;
case EXIT:
Save_catact(&p1);//保存通信录数据
free(p1.data);
p1.data=NULL;
break;
default:
printf("输入错误请重新输入\n");
}
}
while(input);
return 0;
}
//第二个源文件为contact.c
#include "contast.h"
static int Find_name(struct contact* p,char* name)//设置为静态的原因是让他只能再contact.c文件内使用
{
int i=0;
for(i=0;i<p->size;i++)//最多查找size次
{
if(0==strcmp(p->data[i].name,name))//比较两个字符串是否相同,相同返回i
return i;
}
return -1;//没查找到相同的字符串直接返回-1
}
void Just_capacity(struct contact* p)//判断是否需要扩容
{
if(p->size==p->capacity)
{
struct people* ret=(struct people*)realloc(p->data,(p->capacity+2)*sizeof(struct people));
if(ret!=NULL)
{
p->data=ret;
p->capacity+=2;
printf("扩容成功\n");
}
else
printf("%s",strerror(errno));
}
}
void ADD_contact(struct contact* p)//添加联系人
{
Just_capacity(p);
printf("姓名:");
scanf("%s",p->data[p->size].name);
printf("电话:");
scanf("%s",p->data[p->size].number);
printf("地址:");
scanf("%s",p->data[p->size].address);
printf("性别:");
scanf("%s",p->data[p->size].sex);
printf("年龄:");
scanf("%d",&(p->data[p->size].age));//再添加age的时候需要注意的是需要取地址,因为age是一个int类型变量,其他为字符类型
p->size++;//size是计算通信率中人的个数
printf("添加成功\n");
}
void SHOW_contact(struct contact* p)//显示通信录
{
int i=0;
printf("%-10s %-11s %-10s %-5s %s\n","名字","电话","地址","性别","年龄");//负号表示左对齐,数字表示空多少个格
for(i=0;i<p->size;i++)
{
printf("%-10s %-11s %-10s %-5s %-4d\n",p->data[i].name,p->data[i].number,p->data[i].address,p->data[i].sex,p->data[i].age);
}
}
void DEL_contact(struct contact* p)
{
char name[NAME_MAX]={0};
int j=0;
printf("请输入你所要删除的名字:");
scanf("%s",name);
j=Find_name(p,name);//返回的值,为查找到的第一个名字所在数组的位置
if(Find_name(p,name)==-1)
printf("没有找到你所输入的联系人:\n");
else
{
for(j=Find_name(p,name);j<p->size-1;j++)
{
p->data[j]=p->data[j+1];//将所删除的位置进行覆盖(将后面的数挪到前面来)
}
p->size--;//由于删除了一个人,则通信录中人的个数减一
}
}
void RESEARCH_contact(struct contact* p)//查找通信录中的某个人
{
char name[NAME_MAX]={0};
int i=0;
printf("请输入你所要查找的名字:");
scanf("%s",name);
i=Find_name(p,name);
if(i==-1)
printf("没有找到你所输入的联系人:\n");
else
{
printf("%-10s %-11s %-10s %-5s %s\n","名字","电话","地址","性别","年龄");
printf("%-10s %-11s %-10s %-5s %-4d\n",p->data[i].name,p->data[i].number,p->data[i].address,p->data[i].sex,p->data[i].age);
}
}
void MODIFY_contact(struct contact* p)//修改通信录中的某个人的信息
{
char name[NAME_MAX]={0};
int i=0;
printf("请输入你所要修改的名字:");
scanf("%s",name);
i=Find_name(p,name);//先查找你所修改的那个人所在位置
if(i==-1)
printf("没有找到你所输入的联系人:\n");
else
{
printf("请输入你要修改的信息:\n");
printf("姓名:");
scanf("%s",p->data[i].name);
printf("电话:");
scanf("%s",p->data[i].number);
printf("地址:");
scanf("%s",p->data[i].address);
printf("性别:");
scanf("%s",p->data[i].sex);
printf("年龄:");
scanf("%d",&(p->data[i].age));
printf("修改成功\n");
}
}
void Save_catact(struct contact* p)
{
int i=0;
FILE* pf=fopen("text.txt","wb");//将通信录以2进制的形式进行写入文件
if(pf==NULL)
{
printf("Save:%s",strerror(errno));
}
for(i=0;i<p->size;i++)
{
fwrite(p->data,sizeof(struct people),1,pf);//进行写入size次
}
fclose(pf);//释放动态内存,每当用到动态内存时,在用完之后都需要释放
pf=NULL;
}
void Load_catact(struct contact* p)//将原本的存储的信息进行读取,以便于这次存入之后下一次就可以直接看到
{
struct people temp={0};
FILE* pf=fopen("text.txt","rb");//打开文件以2进制的形式读取
if(pf==NULL)
{
printf("Load:%s",strerror(errno));
}
while(fread(&temp,sizeof(struct people),1,pf))//fread函数可以读取文件文件的数据,&temp是读取后暂时存放的位置,sizeof(struct people)是每一次读取的大小,1是读取对象的个数,pf是输入流,read函数的返回值如果是未读取到则返回0可跳出循环
{
Just_capacity(p);//判断是否需要扩容
p->data[p->size]=temp;//将temp读取到的数据转存到p->data[p->size]内
p->size++;//每次读取后size的内容加一
}
fclose(pf);//释放动态内存,每当用到动态内存时,在用完之后都需要释放
pf=NULL;//释放完之后并不会将pf的内容置为空指针需要手动置为空指针,防止非法访问
}
//头文件为contact.h
#include <stdio.h>
#include <string.h>
#define NAME_MAX 10
#define NUMBER_MAX 11
#define ADDRESS_MAX 10
#define SEXE_MAX 5
enum option
{
EXIT,
ADD,
DEL,
RESEARCH,
MODIFY,
SHOW,
};
struct people
{
char name[NAME_MAX];
char number[NUMBER_MAX];
char address[ADDRESS_MAX];
char sex[SEXE_MAX];
int age;
};
struct contact
{
struct people* data;//利用了结构体的嵌套
int size;
};
void ADD_contact(struct contact* p);
void SHOW_contact(struct contact* p);
void DEL_contact(struct contact* p);
void RESEARCH_contact(struct contact* p);
void MODIFY_contact(struct contact* p);
void Just_capacity(struct contact* p);
void Save_catact(struct contact* p);
void Load_catact(struct contact* p);