Contact.h
#pragma once
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<assert.h>
#include<stdlib.h>
#define INCREASE_MAX 2
#define INIT_MAX 3
typedef struct Contact
{
char name[20];
int age;
char sex[10];
char adress[20];
char tele[20];
}Contact;
//typedef struct Node
//{
// Contact people[100];
// int size;
//}Node;
//动态通讯录
typedef struct Node
{
Contact* people;
int size;
int capacity;
}Node;
//开始容量为INIT_MAX 3
//后来增加容量,每次增容INCREASE_MAX 2
void Add(Node* pc);
void Init(Node* pc);
void Show(Node* pc);
void Search(Node* pc);
void Delect(Node* pc);
void Modify(Node* pc);
void Destroy(Node* pc);
void saveContact(Node* pc);
void loadContact(Node* pc);
Contact.c
#include"Contact.h"
//动态版本
void check_capacity(Node* pc)
{
assert(pc);
if (pc->size == pc->capacity)
{
Contact* ptr = (Contact*)realloc(pc->people,sizeof(Contact)* (INCREASE_MAX+INIT_MAX));
if (ptr == NULL)
{
perror("check::realloc");
return;
}
pc->people = ptr;
pc->capacity += INCREASE_MAX;
printf("增容成功\n");
}
}
//动态版本
void Add(Node* pc)
{
//断言处理,判断pc是否为空
assert(pc);
//检查容量
check_capacity(pc);
//获取联系人各项信息
printf("请输入姓名->");
scanf("%s", pc->people[pc->size].name);
printf("请输入年龄->");
scanf("%d", &(pc->people[pc->size].age));
printf("请输入性别->");
scanf("%s", pc->people[pc->size].sex);
printf("请输入地址->");
scanf("%s", pc->people[pc->size].adress);
printf("请输入电话->");
scanf("%s", pc->people[pc->size].tele);
//联系人数量+1
pc->size++;
printf("增加成功\n");
}
void Init(Node* pc)
{
assert(pc);
//pc->size = 0;
//memset(pc->people, 0, sizeof(Contact) * 100);
Contact* ptr = (Contact*)malloc(sizeof(Contact) * INIT_MAX);
if (ptr == NULL)
{
perror("Add::malloc");
return;
}
else
{
pc->people = ptr;
}
pc->size = 0;
pc->capacity = INIT_MAX;
printf("初始化成功\n");
}
void Destroy(Node* pc)
{
//先释放结构体中指针所维护空间,再置空整个结构体
//若先释放结构体,则结构体中指针所维护的空间无法释放,会出现问题
free(pc->people);
pc->people = NULL;
pc->size = pc->capacity = 0;
free(pc);
pc = NULL;
}
void Show(Node* pc)
{
//断言处理,判断pc是否为空
assert(pc);
int i = 0;
//判断通讯录是否为空
if (pc->size == 0)
{
printf("通讯录为空\n");
return;
}
printf("%-10s%-6s%-6s%-10s%-15s\n","姓名","年龄","性别","地址","电话");
for(i = 0; i < pc->size; i++)
{
printf("%-10s%-6d%-6s%-10s%-15s\n", pc->people[i].name,
pc->people[i].age,
pc->people[i].sex,
pc->people[i].adress,
pc->people[i].tele);
}
}
int find_name(Node* pc)
{
assert(pc);
int i = 0;
char name[20];
printf("请输入要查找人的姓名->");
scanf("%s", name);
for (i = 0; i < pc->size; i++)
{
if (strcmp(pc->people[i].name, name) == 0)
return i;
}
return -1;
}
void Search(Node* pc)
{
assert(pc);
int ret = find_name(pc);
if (ret == -1)
printf("没找到\n");
else
{
printf("要查找人的信息->");
printf("%-10s%-6d%-6s%-10s%-15s\n", pc->people[ret].name,
pc->people[ret].age,
pc->people[ret].sex,
pc->people[ret].adress,
pc->people[ret].tele);
}
}
void Delect(Node* pc)
{
assert(pc);
int ret = find_name(pc);
if (ret == -1)
{
printf("要删除的人未查找到\n");
return;
}
//将要删除联系人后面的人的信息前挪
int i = 0;
for (i = ret; i < pc->size - 1; i++)
{
pc->people[i] = pc->people[i + 1];
}
pc->size--;
printf("删除成功\n");
//将最后一个人的信息填补要删除人的信息
}
void Modify(Node* pc)
{
assert(pc);
int ret = find_name(pc);
if (ret == -1)
{
printf("要修改联系人未查找到\n");
return;
}
printf("请输入姓名->");
scanf("%s", pc->people[ret].name);
printf("请输入年龄->");
scanf("%d", &(pc->people[ret].age));
printf("请输入性别->");
scanf("%s", pc->people[ret].sex);
printf("请输入地址->");
scanf("%s", pc->people[ret].adress);
printf("请输入电话->");
scanf("%s", pc->people[ret].tele);
pc->size++;
printf("修改完毕\n");
}
void saveContact(Node* pc)
{
FILE* pf = fopen("Contact.txt", "wb");
if (pf == NULL)
{
perror("fopen");
exit(-1);
}
//读写文件
int i = 0;
for (i = 0; i < pc->size; i++)
{
fwrite(pc->people + i, sizeof(Contact), 1, pf);
}
fclose(pf);
pf = NULL;
printf("保存成功\n");
}
void loadContact(Node* pc)
{
FILE* pf = fopen("Contact.txt", "rb");
if (pf == NULL)
{
perror("fopen");
exit(1);
}
int i = 0;
Contact tmp = { 0 };
//要先判断容量是否充足再将读取到的数据加入通讯录中
//因此fread第一个参数是新定义的变量而不是pc->people+i
while(fread(&tmp,sizeof(Contact),1,pf))//未读取到数据返回0
{
check_capacity(pc);
pc->people[i] = tmp;
pc->size++;
i++;
}
fclose(pf);
pf = NULL;
}
test.c
#include"Contact.h"
void menu()
{
printf("-----------------------------\n");
printf("-----1.Delect 2.Search -----\n");
printf("-----3.Modify 4.Show -----\n");
printf("-----5.Add 0.exit -----\n");
printf("-----------------------------\n");
}
enum Con
{
Exit,
delect,
search,
modify,
show,
add
};
int main()
{
int input = 0;
Node pc;
Init(&pc);
//加载通讯录信息
loadContact(&pc);
do
{
menu();
printf("请输入选项->");
scanf("%d", &input);
switch (input)
{
case delect:
Delect(&pc);
break;
case search:
Search(&pc);
break;
case modify:
Modify(&pc);
break;
case show:
Show(&pc);
break;
case add:
Add(&pc);
break;
case Exit:
saveContact(&pc);
printf("退出程序\n");
break;
default:
printf("选择错误,请重新选择\n");
}
} while (input);
return 0;
}