文件版动态通讯录

该程序设计了一个动态通讯录,解决了之前版本在程序关闭后丢失联系人数据的问题。通过文件读写功能,现在可以保存和加载联系人信息。包括初始化、添加、删除、查找、修改、显示、排序和清空等操作,使用结构体存储个人信息,并进行了内存管理以适应数据增删。
摘要由CSDN通过智能技术生成

动态通讯录文件版

上几个版本的通讯录都是程序关闭后通讯录的内容都全部自动销毁了没有保存联系人数据,现在对这一缺点进行填补,便实现了联系人在程序关闭后依旧能实现保存

增加补充的内容

文件的读取

void SaveContact(contact* c)
{
	FILE* pf = fopen("contact.dat", "wb");
	if (pf == NULL)
	{
		perror("SaveContact::fopen");
		return;
	}
	//写数据
	int i = 0;
	for (i = 0; i < c->sz; i++)
	{
		fwrite(c->data + i, sizeof(struct Peopleidfaction), 1, pf);
	}
	//关闭文件
	fclose(pf);
	pf = NULL;
	printf("保存成功...\n");
}

初始化的改造,文件加载信息

void LoadContact(contact* c)
{
	//打开文件
	FILE* pf = fopen("contact.dat", "rb");
	if (pf == NULL)
	{
		perror("LoadContact::fopen");
		return;
	}
	//读文件
	pd tmp = { 0 };
	while (fread(&tmp, sizeof(pd), 1, pf))
	{
		CheckCapacity(c);
		c->data[c->sz] = tmp;
		c->sz++;
	}

	//关闭文件
	fclose(pf);
	pf = NULL;
}
void initialization(contact* c)
{
	c->data = (pd*)malloc(DEFAULT_sz * sizeof(pd));
	if (c->data == NULL)
	{
		printf("通讯录初始化失败:%s\n", strerror(errno));
		return;
	}
	c->sz = 0;
	memset(c->data, 0, sizeof(c->data));
	c->capacity = DEFAULT_sz;

	//加载文件的信息到通讯录
	LoadContact(c);
}

文件通讯录全部代码

contact.h

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<errno.h>
#define MAX 100
#define NAME 20
#define SEX 5
#define TEL 20
#define ADDR 30
#define DEFAULT_sz 3
#define INC_SZ 2
//个人信息的存储
typedef struct Peopleidfaction
{
    char name[NAME];
    int age;
    char sex[SEX];
    char tel[TEL];
    char addr[ADDR];
}pd;
//通讯录的内容大小限制和数据数
typedef struct contact
{
    int sz;
    //通讯录存入信息量
    pd* data;
    //通讯录存入信息数据数组
    int capacity;
}contact;
//初始化数组
void initialization(contact* c);
//添加联系人的函数声明
void Add(contact* c);
//删除联系人的函数声明
void DestroyContact(contact* c);
//销毁通讯录
void del(contact* c);
//查找该联系人的判断
static int Find_by_name(char name[], const contact* c);
//查询联系人的信息
void Search(const contact* c);
//修改联系人信息
void Modify(contact* c);
//排序联系人信息
void Qsort(contact* c);
//清空所有联系人
void Clear(contact* c);
//显示所有联系人
void Show(const contact* c);
//保存数据到文件
void SaveContact(contact* c);

test.c

#define _CRT_SECURE_NO_DEPRECATE 1
#include"contact.h"
void menu()
{
    printf("****************************************\n");
    printf("*******    1. ADD    2. DEL     ********\n");
    printf("*******    3. SEARCH 4. MODIFY  ********\n");
    printf("*******    5. SHOW   6. CLEAR   ********\n");
    printf("*******    7. QSORT  0. EXIT    ********\n");
    printf("****************************************\n");
}
enum funtion
{
    EXIT,
    ADD,
    DEL,
    SEARCH,
    MODIFY,
    SHOW,
    CLEAR,
    QSORT
};
int main()
{
    int input = 0;
    contact con;
    initialization(&con);
    do
    {
        menu();//打印菜单界面
        scanf("%d", &input);//输入选择
        switch (input)
        {
        case ADD:
            //增加联系人的功能
            Add(&con);
            break;
        case DEL:
            //删除联系人的功能
            del(&con);
            break;
        case SEARCH:
            //查找联系人的功能
            Search(&con);
            break;
        case MODIFY:
            //修改联系人的功能
            Modify(&con);
            break;
        case SHOW:
            //显示联系人的功能
            Show(&con);
            break;
        case CLEAR:
            //清除所有联系人的功能
            Clear(&con);
            break;
        case QSORT:
            //排序联系人的功能,可以通过初始化来操作
            Qsort(&con);
            break;
        case EXIT:
            //退出程序
            SaveContact(&con);
            DestroyContact(&con);
            printf("退出程序\n");
            break;
        default:
            printf("选择错误\n");
            break;
        }
    } while (input);
    return 0;
}

contact.c

#define _CRT_SECURE_NO_DEPRECATE 1
#include"contact.h"
int CheckCapacity(contact* c);

void LoadContact(contact* c)
{
	//打开文件
	FILE* pf = fopen("contact.dat", "rb");
	if (pf == NULL)
	{
		perror("LoadContact::fopen");
		return;
	}
	//读文件
	pd tmp = { 0 };
	while (fread(&tmp, sizeof(pd), 1, pf))
	{
		CheckCapacity(c);
		c->data[c->sz] = tmp;
		c->sz++;
	}

	//关闭文件
	fclose(pf);
	pf = NULL;
}
void initialization(contact* c)
{
	c->data = (pd*)malloc(DEFAULT_sz * sizeof(pd));
	if (c->data == NULL)
	{
		printf("通讯录初始化失败:%s\n", strerror(errno));
		return;
	}
	c->sz = 0;
	memset(c->data, 0, sizeof(c->data));
	c->capacity = DEFAULT_sz;

	//加载文件的信息到通讯录
	LoadContact(c);
}
//查询联系人姓名单独分装一个函数
static int Find_by_name(char name[], const contact* c)
{
	//将输入的name与通讯录中的name进行比对,找到返回位置
	//找不到返回-1
	for (int i = 0; i < c->sz; i++)
	{
		if (strcmp(c->data[i].name, name) == 0)
		{
			return i;
		}
	}
	return -1;
}
int CheckCapacity(contact* c)

{
	if (c->sz == c->capacity)
	{
		pd* ptr = (pd*)realloc(c->data, (c->capacity + INC_SZ) * sizeof(pd));
		if (ptr == NULL)
		{
			printf("CheckCapacity:%s\n", strerror(errno));
			return 0;
		}
		else
		{
			c->data = ptr;
			c->capacity += INC_SZ;
			printf("扩容成功,当前容量为%d\n", c->capacity);
			return 1;
		}
	}
}
void Add(contact* c)//增加联系人的个数
{
	if (CheckCapacity(c) == 0)
	{
		printf("空间不够,扩容失败\n");
		return;
	}
	else
	{
		printf("请输入姓名\n");
		scanf("%s", c->data[c->sz].name);
		printf("请输入性别\n");
		scanf("%s", c->data[c->sz].sex);
		printf("请输入年龄\n");
		scanf("%d", &(c->data[c->sz].age));
		printf("请输入电话\n");
		scanf("%s", c->data[c->sz].tel);
		printf("请输入住址\n");
		scanf("%s", c->data[c->sz].addr);

		c->sz++;//输入完联系人数目+1
		printf("添加成功\n");
	}
}
//删除联系人
void del(contact* c)
{
	char name[NAME] = { 0 };
	//创建一个存名字的数组
	if (c->sz == 0)
	{
		printf("通讯录无联系人,退出操作\n");
		return;
	}
	printf("请输入你要删除的联系人的姓名:");
	scanf("%s", name);
	int ret = Find_by_name(name, c);
	if (ret == -1)
	{
		printf("对不起,该联系人不存在");
		return;
	}
	int i = 0;
	//删除-删除ret位置上的数据
	for (i = ret; i < c->sz - 1; i++)
	{
		c->data[i] = c->data[i + 1];
	}
	c->sz--;
	printf("删除成功\n");
}
//查询联系人
void Search(const contact* c)
{
	char name[NAME] = { 0 };
	printf("请输入要查找人的名字:>");
	scanf("%s", name);
	//向通讯录查询联系人姓名
	int ret = Find_by_name(name, c);
	if (-1 == ret)
	{
		printf("对不起,你所搜索的联系人不存在\n");
		return;
	}
	//姓名      年龄      性别     电话      地址
	//zhangsan 20        男      123456    北京
	printf("%-10s %-5s %-5s %-12s %-30s\n", "姓名", "年龄", "性别", "电话", "地址");
	printf("%-10s %-5d %-5s %-12s %-30s\n",
		c->data[ret].name,
		c->data[ret].age,
		c->data[ret].sex,
		c->data[ret].tel,
		c->data[ret].addr);
}
//修改联系人信息
void Modify(contact* c)
{
	char name[NAME] = { 0 };
	printf("请输入你要修改的联系人姓名");
	scanf("%s", name);
	int ret = Find_by_name(name, c);
	if (-1 == ret)
	{
		printf("对不起,该联系人不存在");
		return;
	}
	printf("请输入姓名\n");
	scanf("%s", c->data[c->sz].name);
	printf("请输入性别\n");
	scanf("%s", c->data[c->sz].sex);
	printf("请输入年龄\n");
	scanf("%d", &(c->data[c->sz].age));
	printf("请输入电话\n");
	scanf("%s", c->data[c->sz].tel);
	printf("请输入住址\n");
	scanf("%s", c->data[c->sz].addr);
	printf("修改成功\n");
}
//展现通讯录表
void Show(const contact* c)
{
	//格式化
	//姓名    年龄      性别    电话     地址
	//李四    20       男      133      上海
	printf("%-10s %-5s %-5s %-12s %-30s\n", "姓名", "年龄", "性别", "电话", "地址");
	for (int i = 0; i < c->sz; i++)
	{
		printf("%-10s %-5d %-5s %-12s %-30s\n",
			c->data[i].name,
			c->data[i].age,
			c->data[i].sex,
			c->data[i].tel,
			c->data[i].addr);
	}
}
int cmp_by_name(const void* p1, const void* p2)
{
	return strcmp(((pd*)p1)->name, ((pd*)p2)->name);
}
//快排函数
void Qsort(contact* c)
{
	int sz = sizeof(c->data) / sizeof(c->data[0]);
	qsort(c->data, c->sz, sizeof(pd), cmp_by_name);
	printf("排序成功!\n");
}
void Clear(contact* c)
{
	initialization(c);
	printf("清除成功!\n");
}
void DestroyContact(contact* c)
{
	free(c->data);
	c->data = NULL;
	c->capacity = 0;
	c->sz = 0;
	printf("释放内存......\n");
}
void SaveContact(contact* c)
{
	FILE* pf = fopen("contact.dat", "wb");
	if (pf == NULL)
	{
		perror("SaveContact::fopen");
		return;
	}
	//写数据
	int i = 0;
	for (i = 0; i < c->sz; i++)
	{
		fwrite(c->data + i, sizeof(struct Peopleidfaction), 1, pf);
	}
	//关闭文件
	fclose(pf);
	pf = NULL;
	printf("保存成功...\n");
}

以上便是文件版通讯录的全部内容

  • 5
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值