✨✨通讯录功能:大家好,我是青衫,这期我们来模拟实现一个能够存储数据的动态内存通讯录
✨✨所要用到的函数:1、添加联系人
2、删除联系人
3、查找联系人
4、修改联系人
5、保存已经存储的联系人(存储进文件,以便下次运行时读取)
6、展示通讯录
7、退出通讯录
文件准备1、打印菜单-------void menu()
2、初始化通讯录-------void inint_contact(Contact* pc)
3、添加联系人-------void add_contact(Contact* pc)
4、删除联系人-------void add_contact(Contact* pc)
5、查找联系人-------void find_contact(Contact* pc)
6、修改联系人-------void modify_contact(Contact* pc)
7、展示联系人-------void show_contact(Contact* pc)
8、检查通讯录是否已满-------void check_contact(Contact* pc)
9、文件存储通讯录数据-------void save_contact(Contact* pc)
10、加载文件中的数据-------void load_contact(Contact* pc)
11、销毁通讯录-------void destroy_contact(Contact* pc)
12、通过名字查找-------static int find_per_by_name(Contact* pc,char name[ ])
一个名为“contact.h”的头文件,一个名为“contact.c”的源文件,一个“test.c”的源文件。两个源文件分别包含头文件。
源文件准备工作包含头文件以及宏定义和结构体定义:
#pragma once #include#include #include #include #define DEFAULT_SZ 3 #define INC 2 #define MAX_NAME 10 #define MAX_TELE 12 #define MAX_ADDRESS 100 #define MAX_SEX 5 //人 typedef struct Person { char name[MAX_NAME]; char tele[MAX_TELE]; char address[MAX_ADDRESS]; char sex[MAX_SEX]; int age; }Person; typedef struct Contact { //人物数据 Person* data; //存储的数量 int size; //总容量 int capacity; }Contact; 函数声明:
//添加 void add_contact(Contact* pc); //删除 void delete_contact(Contact* pc); //查找 void find_contact(Contact* pc); //修改 void modify_contact(Contact* pc); //销毁通讯录 void destroy_contact(Contact* pc); //初始化通讯录 void inint_contact(Contact* pc); //检查通讯录是否满了 void check_contact(Contact* pc); //展示通讯录 void show_contact(Contact* pc); //文件保存通讯录 void save_contact(Contact* pc); //加载文件中的通讯录联系人信息 void load_contact(Contact* pc);
接下来我们该实现函数了
1.1打印菜单
void menu()
{
printf("************************************n");
printf("***** 1、添加 2、删除 *********n");
printf("*******3、查找 4、修改 *********n");
printf("***********5、展示联系人************n");
printf("*********** 0、退出 **************n");
printf("************************************n");
}
1.2初始化通讯录
1.3 检查通讯录是否已满void inint_contact(Contact* pc) { assert(pc); pc->size = 0; pc->capacity = 2; pc->data = (Person*)malloc(DEFAULT_SZ * sizeof(Person)); if (pc->data == NULL) { perror("InitContact::malloc"); return; } //加载文件中存储好的通讯录联系人信息 load_contact(pc); }这里用malloc开辟足够的空间来存储联系人。
load_Contact函数是读取文件中的数据的函数,后文会讲到如何实现。
1.4添加联系人void check_contact(Contact* pc) { if (pc->size == pc->capacity) { Person* ptr = realloc(pc->data, (pc->capacity + INC) * sizeof(Person)); if (ptr != NULL) { pc->data = ptr; pc->capacity += INC; printf("增容成功n"); } else { perror("add_contact realloc"); return; } } }这里判断容量capacity是否足够,如果不足了,就用realloc来扩容。扩容后capacity也应该加上扩容的容量。
1.5通过输入的名字查找到联系人void add_contact(Contact* pc) { assert(pc); check_contact(pc); printf("请输入姓名-> "); scanf("%s", &pc->data[pc->size].name); printf("请输入电话-> "); scanf("%s", &pc->data[pc->size].tele); printf("请输入地址-> "); scanf("%s", &pc->data[pc->size].address); printf("请输入性别-> "); scanf("%s", &pc->data[pc->size].sex); printf("请输入年龄-> "); scanf("%d", &pc->data[pc->size].age); pc->size++; printf("添加成功n"); }先断言判断传入的指针非空。
之后逐个输入即可。
1.6删除联系人static int find_per_by_name(Contact* pc,char name[]) { assert(pc); int i = 0; for (int i = 0; i < pc->size; i++) { if (strcmp(pc->data[i].name, name) == 0) { return i; } } return -1; }通过输入的姓名,遍历查找整个通讯录,如果发现相同名字的,那么就返回其对应的下标。
如果找不到,返回-1;
注:这里因为只是在这个文件中实现其他函数的时候用到这个函数,所以用static来声明保护它,让它不能在其他文件中使用。
1.7查找联系人void delete_contact(Contact* pc) { assert(pc); if (pc->size == 0) { printf("通讯录为空n"); } else { char name[MAX_NAME] = { 0 }; printf("请输入要删除的人的姓名n"); scanf("%s", name); int pos = find_per_by_name(pc, name); if (pos == -1) { printf("不存在此人n"); } else { int j = 0; for (j = pos; j < pc->size - 1; j++) { pc->data[j] = pc->data[j + 1]; } pc->size--; printf("删除成功n"); } } }输入要删除的联系人的姓名,然后通过前面实现的 find_per_by_name 函数来查找的所要删除的联系人的下标,然后从后往前覆盖数据,再将通讯录的大小-1即可。
1.8修改联系人void find_contact(Contact* pc) { assert(pc); char name[MAX_NAME] = { 0 }; printf("请输入要查找的人名->"); scanf("%s", name); int pos = find_per_by_name(pc, name); if (pos == -1) { printf("不存在此人n"); } else { printf("姓名:%sn", pc->data[pos].name); printf("性别:%sn", pc->data[pos].sex); printf("年龄:%dn", pc->data[pos].age); printf("电话:%sn", pc->data[pos].tele); printf("地址:%sn", pc->data[pos].address); printf("n"); } }还是通过find_per_by_name 函数来查找联系人,然后打印他的信息。
1.9展示通讯录的联系人void modify_contact(Contact* pc) { assert(pc); char name[MAX_NAME] = { 0 }; printf("请输入要查找的人名->"); scanf("%s", name); int pos = find_per_by_name(pc, name); if (pos == -1) { printf("不存在此人n"); } else { printf("请输入姓名-> "); scanf("%s", &pc->data[pc->size].name); printf("请输入电话-> "); scanf("%s", &pc->data[pc->size].tele); printf("请输入地址-> "); scanf("%s", &pc->data[pc->size].address); printf("请输入性别-> "); scanf("%s", &pc->data[pc->size].sex); printf("请输入年龄-> "); scanf("%d", &pc->data[pc->size].age); printf("修改成功!n"); } }通过find_per_by_name 函数来查找联系人,然后重新输入新的联系人信息。
2.0销毁通讯录void show_contact(Contact* pc) { assert(pc); int i = 0; if (pc->size == 0) { printf("通讯录为空n"); return 1; } for (; i < pc->size; i++) { printf("%dn", i+1); printf("姓名:%sn", pc->data[i].name); printf("性别:%sn", pc->data[i].sex); printf("年龄:%dn", pc->data[i].age); printf("电话:%sn", pc->data[i].tele); printf("地址:%sn", pc->data[i].address); printf("n"); } }将整个通讯录的联系人信息一 一打印一遍。
2.1将通讯录中的联系人存储进文件中void destroy_contact(Contact* pc) { assert(pc); free(pc->data); pc->data = NULL; pc->size = 0; pc->capacity = 0;free释放之前malloc和realloc申请的内存空间,将指针置空,将容量和大小等归零。
2.2读取文件中存储的联系人数据void save_contact(Contact* pc) { FILE* pfwritting = fopen("Contact.dat", "wb"); if (pfwritting == NULL) { perror("open file for writting"); return 1; } //写数据进文件 for (int i = 0; i < pc->size; i++) { fwrite(pc->data + i, sizeof(Person), 1, pfwritting); } fclose(pfwritting); pfwritting = NULL; }fopen打开文件“Contact.dat”,方式为二进制写入。用一个类型为FILE的指针接收。
用fwrite以二进制的形式写入pc->date+i所指向的数据到文件中。
最后fclose关闭文件,将指针置空。
void load_contact(Contact* pc) { Person p1 = { 0 }; FILE* pfreading = fopen("Contact.dat", "rb"); if (pfreading == NULL) { perror("open file for reading"); return; } while (fread(&p1, sizeof(Person), 1, pfreading)) { check_contact(pc); pc->data[pc->size] = p1; pc->size++; } }fopen打开文件,以二进制形式读取。创建Person类型的临时变量p1。
fread将pfreading指向的文件中的内容读取到临时变量p1中。
再用pc->date+i 来接收p1中的内容,存储进通讯录中。
每接收一个,size++;
感谢各位的观看!代码放在最后!
Contact.h#pragma once #include#include #include #include #define DEFAULT_SZ 3 #define INC 2 #define MAX_NAME 10 #define MAX_TELE 12 #define MAX_ADDRESS 100 #define MAX_SEX 5 //人 typedef struct Person { char name[MAX_NAME]; char tele[MAX_TELE]; char address[MAX_ADDRESS]; char sex[MAX_SEX]; int age; }Person; typedef struct Contact { //人物数据 Person* data; //存储的数量 int size; //总容量 int capacity; }Contact; //添加 void add_contact(Contact* pc); //删除 void delete_contact(Contact* pc); //查找 void find_contact(Contact* pc); //修改 void modify_contact(Contact* pc); //销毁通讯录 void destroy_contact(Contact* pc); //初始化通讯录 void inint_contact(Contact* pc); //检查通讯录是否满了 void check_contact(Contact* pc); //展示通讯录 void show_contact(Contact* pc); //文件保存通讯录 void save_contact(Contact* pc); //加载文件中的通讯录联系人信息 void load_contact(Contact* pc);
Contact.c
#define _CRT_SECURE_NO_WARNINGS 1
#include "contact.h"
void load_contact(Contact* pc)
{
Person p1 = { 0 };
FILE* pfreading = fopen("Contact.dat", "rb");
if (pfreading == NULL)
{
perror("open file for reading");
return;
}
while (fread(&p1, sizeof(Person), 1, pfreading))
{
check_contact(pc);
pc->data[pc->size] = p1;
pc->size++;
}
}
void inint_contact(Contact* pc)
{
assert(pc);
pc->size = 0;
pc->capacity = 2;
pc->data = (Person*)malloc(DEFAULT_SZ * sizeof(Person));
if (pc->data == NULL)
{
perror("InitContact::malloc");
return;
}
//加载文件中存储好的通讯录联系人信息
load_contact(pc);
}
void check_contact(Contact* pc)
{
if (pc->size == pc->capacity)
{
Person* ptr = realloc(pc->data, (pc->capacity + INC) * sizeof(Person));
if (ptr != NULL)
{
pc->data = ptr;
pc->capacity += INC;
printf("增容成功n");
}
else
{
perror("add_contact realloc");
return;
}
}
}
void add_contact(Contact* pc)
{
assert(pc);
check_contact(pc);
printf("请输入姓名-> ");
scanf("%s", &pc->data[pc->size].name);
printf("请输入电话-> ");
scanf("%s", &pc->data[pc->size].tele);
printf("请输入地址-> ");
scanf("%s", &pc->data[pc->size].address);
printf("请输入性别-> ");
scanf("%s", &pc->data[pc->size].sex);
printf("请输入年龄-> ");
scanf("%d", &pc->data[pc->size].age);
pc->size++;
printf("添加成功n");
}
static int find_per_by_name(Contact* pc,char name[])
{
assert(pc);
int i = 0;
for (int i = 0; i < pc->size; i++)
{
if (strcmp(pc->data[i].name, name) == 0)
{
return i;
}
}
return -1;
}
void delete_contact(Contact* pc)
{
assert(pc);
if (pc->size == 0)
{
printf("通讯录为空n");
}
else
{
char name[MAX_NAME] = { 0 };
printf("请输入要删除的人的姓名n");
scanf("%s", name);
int pos = find_per_by_name(pc, name);
if (pos == -1)
{
printf("不存在此人n");
}
else
{
int j = 0;
for (j = pos; j < pc->size - 1; j++)
{
pc->data[j] = pc->data[j + 1];
}
pc->size--;
printf("删除成功n");
}
}
}
void show_contact(Contact* pc)
{
assert(pc);
int i = 0;
if (pc->size == 0)
{
printf("通讯录为空n");
return 1;
}
for (; i < pc->size; i++)
{
printf("%dn", i+1);
printf("姓名:%sn", pc->data[i].name);
printf("性别:%sn", pc->data[i].sex);
printf("年龄:%dn", pc->data[i].age);
printf("电话:%sn", pc->data[i].tele);
printf("地址:%sn", pc->data[i].address);
printf("n");
}
}
void find_contact(Contact* pc)
{
assert(pc);
char name[MAX_NAME] = { 0 };
printf("请输入要查找的人名->");
scanf("%s", name);
int pos = find_per_by_name(pc, name);
if (pos == -1)
{
printf("不存在此人n");
}
else
{
printf("姓名:%sn", pc->data[pos].name);
printf("性别:%sn", pc->data[pos].sex);
printf("年龄:%dn", pc->data[pos].age);
printf("电话:%sn", pc->data[pos].tele);
printf("地址:%sn", pc->data[pos].address);
printf("n");
}
}
void modify_contact(Contact* pc)
{
assert(pc);
char name[MAX_NAME] = { 0 };
printf("请输入要查找的人名->");
scanf("%s", name);
int pos = find_per_by_name(pc, name);
if (pos == -1)
{
printf("不存在此人n");
}
else
{
printf("请输入姓名-> ");
scanf("%s", &pc->data[pc->size].name);
printf("请输入电话-> ");
scanf("%s", &pc->data[pc->size].tele);
printf("请输入地址-> ");
scanf("%s", &pc->data[pc->size].address);
printf("请输入性别-> ");
scanf("%s", &pc->data[pc->size].sex);
printf("请输入年龄-> ");
scanf("%d", &pc->data[pc->size].age);
printf("修改成功!n");
}
}
void destroy_contact(Contact* pc)
{
assert(pc);
free(pc->data);
pc->data = NULL;
pc->size = 0;
pc->capacity = 0;
}
void save_contact(Contact* pc)
{
FILE* pfwritting = fopen("Contact.dat", "wb");
if (pfwritting == NULL)
{
perror("open file for writting");
return 1;
}
//写数据进文件
for (int i = 0; i < pc->size; i++)
{
fwrite(pc->data + i, sizeof(Person), 1, pfwritting);
}
fclose(pfwritting);
pfwritting = NULL;
}
test.c
#define _CRT_SECURE_NO_WARNINGS 1
#include "contact.h"
void menu()
{
printf("************************************n");
printf("***** 1、添加 2、删除 *********n");
printf("*******3、查找 4、修改 *********n");
printf("***********5、展示联系人************n");
printf("*********** 0、退出 **************n");
printf("************************************n");
}
int main()
{
Contact con = { 0 };
inint_contact(&con);
int input = 0;
printf("欢迎使用通讯录系统,请选择您要使用的功能: n");
do
{
menu();
scanf("%d", &input);
switch (input)
{
case 1:
add_contact(&con);
break;
case 2:
delete_contact(&con);
break;
case 3:
find_contact(&con);
case 4:
modify_contact(&con);
break;
case 5:
show_contact(&con);
break;
case 0:
save_contact(&con);
destroy_contact(&con);
printf("欢迎下次使用n");
break;
default:
printf("输入有误,请重试n");
break;
}
} while (input);
return 0;
}



