1.contact.c
include"contact.h"
void checkcapity(contact* p);
void loadcontact(contact* p)//将文件中的内容加载进入
{
person tmp = { 0 };
FILE* pfread = fopen("data.txt", "rb");
if (pfread == NULL)
{
perror("loadcontact::fopen");
return;
}
while (fread(&tmp, sizeof(person), 1, pfread))
{
checkcapity(p);
p->data[p->sz] = tmp;
p->sz++;
}
fclose(pfread);
pfread = NULL;
}
void init(contact* p)
{
p->data = (person)malloc(3sizeof(person));
if (p->data == NULL)
{
return;
}
p->sz = 0;
p->capity = 3;
loadcontact(p);
}
void checkcapity(contact* p)
{
if (p->sz == p->capity)//空间已满 要扩容
{
struct person* ptr = (struct person*)realloc(p->data, (p->capity + 2) * sizeof(struct person));//addcap代表增大2个容量
if (ptr != NULL)
{
p->data = ptr;
p->capity = p->capity + 2;//将容量扩大到5 str不需要销毁 它并没有开辟动态空间
printf("扩容成功\n");
}
}
}
void addcontact(contact* p)//增加通讯录成员
{
checkcapity(p);
printf("请输入名字:>");
scanf("%s", p->data[p->sz].name);
printf("请输入年龄:>");
scanf("%d", &p->data[p->sz].age);
printf("请输入性别:>");
scanf("%s", p->data[p->sz].sex);
printf("请输入电话:>");
scanf("%s", p->data[p->sz].tele);
printf("请输入地址:>");
scanf("%s", p->data[p->sz].addr);
p->sz++;
printf("增加成功\n");
}
int find(contact* p, char name[])
{
int i = 0;
for (i = 0; i < p->sz; i++)
{
if (strcmp(name, p->data[i].name) == 0)
{
return i;
}
}
return -1;
}
void delcontact(contact* p)//删除通讯录成员
{
if (p->sz == 0)
{
printf("没有数据可以删除\n");
return;
}
char name[20];
printf("请删除输入名字:>");
scanf("%s", name);
int ret = find(p, name);
if (ret == -1)
{
printf("没找到\n");
return;
}
else
{
int i = 0;
for (i = 0; i < p->sz - 1; i++)//数据到达倒数第二个就会把倒数第一个数传过来
{
p->data[i] = p->data[i + 1];
}
p->sz--;//一共有两个倒数第一个的数的值 故删去最后一个数
}
}
void searchcontact(const contact* p)//查找通讯录成员
{
char name[20];
printf("输入要查找的名字:>");
scanf("%s", name);
int ret = find(p, name);
if (ret == -1)
{
printf("没找到\n");
return;
}
else
{
printf("%20s\t %5s\t %5s\t %20s\t %20s\n", "名字", "年龄", "性别", "电话", "地址");
printf("%20s\t", p->data[ret].name);
printf("%5d\t", p->data[ret].age);
printf("%5s\t", p->data[ret].sex);
printf("%20s\t", p->data[ret].tele);
printf("%20s\n", p->data[ret].addr);
}
}
void modifycontact(contact* p)//修改通讯录成员
{
char name[20];
printf("输入名字:>");
scanf("%s", name);
int ret = find(p, name);
if (ret == -1)
{
printf("没找到该成员\n");
}
else
{
printf("请输修改入名字:>");
scanf("%s", p->data[ret].name);
printf("请输入修改年龄:>");
scanf("%d", &p->data[ret].age);
printf("请输入修改性别:>");
scanf("%s", p->data[ret].sex);
printf("请输入修改电话:>");
scanf("%s", p->data[ret].tele);
printf("请输入修改地址:>");
scanf("%s", p->data[ret].addr);
}
}
void printcontact(contact* p)//输出所有成员
{
int i = 0;
printf("%20s\t %5s\t %5s\t %20s\t %20s\n", "名字", "年龄", "性别", "电话", "地址");
for (i = 0; i < p->sz; i++)
{
printf("%20s\t", p->data[i].name);
printf("%5d\t", p->data[i].age);
printf("%5s\t", p->data[i].sex);
printf("%20s\t", p->data[i].tele);
printf("%20s\n", p->data[i].addr);
}
}
int cmp(const void* e1, const void* e2)
{
return ((struct person)e1)->age - ((struct person)e2)->age;
}
void sortcontact(contact* p)//将结构体成员排序
{
qsort(p->data, p->sz, sizeof(struct person), cmp);
}
void savecontact(contact* p)
{
FILE* pf = fopen("data.txt", "wb");//创建文件
if (pf == NULL)
{
perror("savecontact::fopen");
return;
}
int i = 0;
for (i = 0; i < p->sz; i++)//将内容写入文件
{
fwrite(p->data + i, sizeof(person), 1, pf);
}
fclose(pf);//关闭文件 pf = NULL;
}
void destory(contact* p)
{
free(p->data);
p->data = NULL;
p->capity = 0;
p->sz = 0;
}
2.contact.h
define _CRT_SECURE_NO_WARNINGS
define cap 3//动态内存空间的初始容量
define addcap 2//增大的容量
include
include
include
typedef struct person
{
char name[20];
int age;
char sex[20];
char tele[20];
char addr[20];
}person;
typedef struct contact
{
person* data;//指向动态内存空间 用来存放联系人信息
int sz;//当前记录的个数
int capity;//动态内存的容量
}contact;
void init(contact* p);
void addcontact(contact* p);
void delcontact(contact* p);
void searchcontact(const contact* p);//这里我们只是寻找数据 不修改 用const修饰结构体本身内容不能被修改 起到保护数据的作用
void modifycontact(contact* p);
void printcontact(contact* p);
void sortcontact(contact* p);
void destory(contact* p);
void loadcontact(contact* p);
void savecontact(contact* p);
3.test.c
include"contact.h"
void menu()
{
printf("1.add 2.del\n");
printf("3.search 4.modify\n"); printf("5.sort 6.print\n"); printf("0.ex\n");
}
enum day
{
ex,
add,
del,
search,
modify,
sort,
};
int main()
{
contact con;
init(&con);
int input = 0;
do
{
menu();
printf("请输入数字:>");
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 sort:
sortcontact(&con);
break;
case print:
printcontact(&con);
break;
case ex:
savecontact(&con);
printf("结束");
destory(&con);//销毁内存
break;
default: printf("输入错误 重新输入"); break; } } while (input); return 0;
}