栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

C语言: 可存储数据的动态内存通讯录

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

C语言: 可存储数据的动态内存通讯录

大家好,我是青衫,这期我们来模拟实现一个能够存储数据的动态内存通讯录

✨✨通讯录功能:

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初始化通讯录
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.3 检查通讯录是否已满
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.4添加联系人
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.5通过输入的名字查找到联系人
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.6删除联系人
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.7查找联系人
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.8修改联系人
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 函数来查找联系人,然后重新输入新的联系人信息。

1.9展示通讯录的联系人
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.0销毁通讯录
void destroy_contact(Contact* pc)
{
	assert(pc);
	free(pc->data);
	pc->data = NULL;
	pc->size = 0;
	pc->capacity = 0;

free释放之前malloc和realloc申请的内存空间,将指针置空,将容量和大小等归零。

2.1将通讯录中的联系人存储进文件中
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关闭文件,将指针置空。

2.2读取文件中存储的联系人数据
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;
}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/889430.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号