🎉🎉大家好,我是青衫,这期我们来模拟实现一个能够存储数据的动态内存通讯录🎉🎉
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 <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#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);
接下来我们该实现函数了
void menu()
{
printf("************************************\n");
printf("***** 1、添加 2、删除 *********\n");
printf("*******3、查找 4、修改 *********\n");
printf("***********5、展示联系人************\n");
printf("*********** 0、退出 **************\n");
printf("************************************\n");
}
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函数是读取文件中的数据的函数,后文会讲到如何实现。
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也应该加上扩容的容量。
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;
}
通过输入的姓名,遍历查找整个通讯录,如果发现相同名字的,那么就返回其对应的下标。
如果找不到,返回-1;
注:这里因为只是在这个文件中实现其他函数的时候用到这个函数,所以用static来声明保护它,让它不能在其他文件中使用。
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即可。
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("姓名:%s\n", pc->data[pos].name);
printf("性别:%s\n", pc->data[pos].sex);
printf("年龄:%d\n", pc->data[pos].age);
printf("电话:%s\n", pc->data[pos].tele);
printf("地址:%s\n", pc->data[pos].address);
printf("\n");
}
}
还是通过find_per_by_name 函数来查找联系人,然后打印他的信息。
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 函数来查找联系人,然后重新输入新的联系人信息。
void show_contact(Contact* pc)
{
assert(pc);
int i = 0;
if (pc->size == 0)
{
printf("通讯录为空\n");
return 1;
}
for (; i < pc->size; i++)
{
printf("%d\n", i+1);
printf("姓名:%s\n", pc->data[i].name);
printf("性别:%s\n", pc->data[i].sex);
printf("年龄:%d\n", pc->data[i].age);
printf("电话:%s\n", pc->data[i].tele);
printf("地址:%s\n", pc->data[i].address);
printf("\n");
}
}
将整个通讯录的联系人信息一 一打印一遍。
void destroy_contact(Contact* pc)
{
assert(pc);
free(pc->data);
pc->data = NULL;
pc->size = 0;
pc->capacity = 0;
free释放之前malloc和realloc申请的内存空间,将指针置空,将容量和大小等归零。
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++;
感谢各位的观看!代码放在最后!
#pragma once
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#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("%d\n", i+1);
printf("姓名:%s\n", pc->data[i].name);
printf("性别:%s\n", pc->data[i].sex);
printf("年龄:%d\n", pc->data[i].age);
printf("电话:%s\n", pc->data[i].tele);
printf("地址:%s\n", 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("姓名:%s\n", pc->data[pos].name);
printf("性别:%s\n", pc->data[pos].sex);
printf("年龄:%d\n", pc->data[pos].age);
printf("电话:%s\n", pc->data[pos].tele);
printf("地址:%s\n", 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;
}
#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;
}