当前位置: 首页 > news >正文

C语言《文件版本通讯录》

文章目录

  • 普通版通讯录
  • 动态版通讯录
  • 文件版通讯录
  • 一、文件版通讯录介绍
  • 二、文件版通讯录实现
    • (1)增加SavePhone保存函数
    • (2)增加LoadPhone加载函数
  • 三、文件版通讯录实现结果
  • 四、实现源代码
    • (1)phone.c
    • (2)phone.h
    • (3)test.c

普通版通讯录

[点击可查看普通版通讯录实现](https://blog.csdn.net/m0_59292239/article/details/127024944?spm=1001.2014.3001.5501)

动态版通讯录

[点击可查看动态版通讯录实现](https://blog.csdn.net/m0_59292239/article/details/127194385?spm=1001.2014.3001.5501)

文件版通讯录

一、文件版通讯录介绍

之前的版本,当通讯录退出后,录入的信息退出之后不能看到上次保存的信息,为了解决这个问题,把动态版升级为文件版通讯录。分两步实现,增加两个函数即可。

二、文件版通讯录实现

(1)增加SavePhone保存函数

void SavePhone(struct Phone*pc)
{
	FILE* pf = fopen("data.txt", "wb");
	if (pf == NULL)
	{
		perror("SavePhone");
		return;
	}
	for (int i = 0; i<pc->sz; i++)
	{
		fwrite(pc->data+i,sizeof(struct P),1,pf);
	}
	fclose(pf);
	pf = NULL;
}

第一步是当录入完信息后,把数据保存到文件中。先以二进制写的方式打开文件,此时没有这个文件。会在当前路径下创建一个这样的文件,判断pf是否为空,不为空,就for循环把信息写到这个文件中,用fwrtie函数进行写,pc->data,是连续空间的首地址,加i跳过i个元素,大小为struct P的大小,个数为1,写到pf流中,最后关闭文件。

(2)增加LoadPhone加载函数

void LoadPhone(struct Phone*pc)
{
	FILE*pw=fopen("data.txt", "rb");
	if (pw == NULL)
	{
		perror("LoadPhone");
		return;
	}
	struct P tmp = { 0 };
	while (fread(&tmp, sizeof(struct P), 1, pw))
	{
		check_cap(pc);
		pc->data[pc->sz] = tmp;
		pc->sz++;
	}
	fclose(pw);
	pw = NULL;

}

第二步是下次运行该程序的时候,能够显示上次保存的数据。
在初始函数InitPhone增加一个加载函数 LoadPhone。先以二进制读的方式打开这个文件,判断pw是否为空,不为空,使用while循环进行把文件的信息录入(读)到通讯录中,用fread函数进行读,先创建一个结构体P的变量 tmp,先把文件中的信息读到tmp中,再把tmp放在pc->data[pc->sz]为pc->sz的位置上。又因为从文件录入的信息个数可能大于初始容量,所以要调用check_cap函数进行检查,如果不够就增容。

三、文件版通讯录实现结果

在这里插入图片描述
在这里插入图片描述
先录入信息,完之后退出,再运行该程序show查看保存的信息。

四、实现源代码

(1)phone.c

#include"phone.h"
static int check_cap(struct Phone * pc);
void LoadPhone(struct Phone*pc)
{
	FILE*pw=fopen("data.txt", "rb");
	if (pw == NULL)
	{
		perror("LoadPhone");
		return;
	}
	struct P tmp = { 0 };
	while (fread(&tmp, sizeof(struct P), 1, pw))
	{
		check_cap(pc);
		pc->data[pc->sz] = tmp;
		pc->sz++;
	}
	fclose(pw);
	pw = NULL;

}
void InitPhone(struct Phone* pc)
{
	assert(pc);
	pc->data = (struct P *)malloc(sizeof(struct P) * De_sz);
	if (pc->data == NULL)
	{
		perror("InitPhone");
		return;
	}
	pc->sz = 0;
	pc->cap = De_sz;
	LoadPhone(pc);

}
int check_cap(struct Phone * pc)
{
	if (pc->sz == pc->cap)
	{
		struct P *ptr = (struct P *)realloc(pc->data,sizeof(struct P)*(pc->cap + Add_sz));
		if (ptr != NULL)
		{
			pc->data = ptr;
			pc->cap += Add_sz;
			printf("增容成功\n");
			return 1;
		}
		else
		{
			perror("AddPhone");
			return 0;
		}
	}
	else
	{
		return 1;
	}
}
void AddPhone(struct Phone* pc)
{
	assert(pc);
	if (check_cap(pc)==0)
	{
		return;
	}
		printf("输入名字:");
		scanf("%s", pc->data[pc->sz].name);
		printf("输入性别:");
		scanf("%s", pc->data[pc->sz].sex);
		printf("输入年龄:");
		scanf("%d", &(pc->data[pc->sz].age));
		printf("输入电话号码:");
		scanf("%s", pc->data[pc->sz].tel);
		printf("输入地址:");
		scanf("%s", pc->data[pc->sz].adress);
		pc->sz++;
		printf("成功添加\n");
	
}
void ShowPhone(struct Phone* pc)
{
	printf("%-20s\t%-5s\t%-10s\t%-13s\t%-30s\n", "姓名","性别","年龄","电话号码","地址");
	for (int i = 0; i < pc->sz; i++)
	{
		printf("%-20s\t%-5s\t%-10d\t%-13s\t%-30s\n", pc->data[i].name, pc->data[i].sex,
			pc->data[i].age, pc->data[i].tel, pc->data[i].adress);
	}
}
int Find_name(struct Phone* pc, char name[])
{
	for (int i = 0; i < pc->sz; i++)
	{
		if (strcmp(pc->data[i].name, name) == 0)
		{
			return i;
		}
	}
	return -1;
}
void  DelPhone(struct Phone* pc)
{
	char name[MAX_name];
	printf("输入删除的名字:");
	scanf("%s", name);
	int ret = Find_name(pc, name);
	if (ret == -1)
	{
		printf("删除的人不存在");
	}
	else
	{
		for (int j = ret; j < pc->sz; j++)
		{
			pc->data[j] = pc->data[j + 1];
		}
		pc->sz--;
		printf("已删除改联系人\n");
	}
}
void ModifyPhone(struct Phone* pc)
{
	char name[MAX_name];
	printf("输入修改的名字:");
	scanf("%s", name);
	int ret = Find_name(pc, name);
	if (ret == -1)
	{
		printf("修改的人不存在");
	}
	else
	{
		printf("输入名字:");
		scanf("%s", pc->data[ret].name);
		printf("输入性别:");
		scanf("%s", pc->data[ret].sex);
		printf("输入年龄:");
		scanf("%d", &(pc->data[ret].age));
		printf("输入电话号码:");
		scanf("%s", pc->data[ret].tel);
		printf("输入地址:");
		scanf("%s", pc->data[ret].adress);
		printf("已修改改联系人\n");
	}
}
int cmp_name(const void* e1,const void* e2)
{
	return strcmp(((struct P*)e1)->name ,((struct P*)e2)->name);
}
void SortPhone(struct Phone* pc)
{
	qsort(pc->data,pc->sz,sizeof(struct P),cmp_name);
}
void SearchPhone(struct Phone* pc)
{
	char name[MAX_name];
	printf("输入搜索的名字:");
	scanf("%s", name);
	int ret = Find_name(pc, name);
	if (ret == -1)
	{
		printf("搜索的人不存在");
	}
	else
	{
		printf("%-20s\t%-5s\t%-10s\t%-13s\t%-30s\n", "姓名", "性别", "年龄", "电话号码", "地址");
		printf("%-20s\t%-5s\t%-10d\t%-13s\t%-30s\n", pc->data[ret].name, pc->data[ret].sex,
			pc->data[ret].age, pc->data[ret].tel, pc->data[ret].adress);
	}
}
void DestroyPhone(struct Phone*pc)
{
	free(pc->data);
	pc->data = NULL;
	pc->cap = 0;
	pc->sz = 0;
}
void SavePhone(struct Phone*pc)
{
	FILE* pf = fopen("data.txt", "wb");
	if (pf == NULL)
	{
		perror("SavePhone");
		return;
	}
	for (int i = 0; i<pc->sz; i++)
	{
		fwrite(pc->data+i,sizeof(struct P),1,pf);
	}
	fclose(pf);
	pf = NULL;
}


(2)phone.h

#pragma once
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<assert.h>
#define MAX_name 20
#define MAX_sex 5
#define MAX_tel 13
#define MAX_addr 30
#define De_sz 3
#define Add_sz 2

struct P
{
	char name[MAX_name];
	char sex[MAX_sex];
	int age;
	char tel[MAX_tel];
	char adress[MAX_addr];
};
struct Phone
{
	struct P *data;
	int sz;
	int cap;
};

void InitPhone(struct Phone* pc);

void AddPhone(struct Phone* pc);
void DelPhone(struct Phone* pc);
void SearchPhone(struct Phone* pc);
void ModifyPhone(struct Phone* pc);
void ShowPhone(struct Phone* pc);
void SortPhone(struct Phone* pc);

int Find_name(struct Phone* pc, char name[]);
int cmp_name(const void* e1, const void* e2);
int check_cap(struct Phone * pc);
void DestroyPhone(struct Phone*pc);

void SavePhone(struct Phone*pc);
void LoadPhone(struct Phone*pc);

(3)test.c

#include"phone.h"
void menu()
{
	printf("***************************************\n");
	printf("*******    1、add       2、del    *******\n");
	printf("*******    3、search    4、modify *******\n");
	printf("*******    5、show      6、sort   *******\n");
	printf("*******         0、exit           *******\n");
	printf("***************************************\n");
}
int main()
{
	int input = 0;
	struct Phone con;
	InitPhone(&con);
	do
	{
		menu();
		printf("请选择->");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			AddPhone(&con);
			break;
		case 2:
			DelPhone(&con);
			break;
		case 3:
			SearchPhone(&con);
			break;
		case 4:
			ModifyPhone(&con);
			break;
		case 5:
			ShowPhone(&con);
			break;
		case 6:
			SortPhone(&con);
			break;
		case 0:
			SavePhone(&con);
			DestroyPhone(&con);
			printf("退出成功\n");
			break;
		default:
			printf("选择错误\n");
			break;
		}
	} while (input);
	return 0;
}

相关文章:

  • ASAN
  • 爬虫抓取网站数据
  • 【Git教程】(十七)发行版交付 — 概述及使用要求,执行过程及其实现,替代解决方案 ~
  • node.js 解析post请求 方法一
  • 【漏洞复现】云时空社会化商业ERP系统LoginName SQL注入漏洞
  • 嵌入式4-24
  • 基于java Springboot实现课程评分系统设计和实现
  • HUAWEI Programming Contest 2024(AtCoder Beginner Contest 342)
  • python Matplotlib Tkinter-->tab切换2
  • DSMM申报通道已开通,一起来看看吧!
  • FullCalendar日历组件:进行任务增删改,参考gitee例子修改
  • [Docker 教学] 常用的Docker 命令
  • 【无人机】基于EKF、UKF、PF、改进PF滤波算法的无人机航迹预测(Matlab代码实现)
  • 一篇文章让你搞懂Java中的静态代理和动态代理
  • ROS1云课-导航实践测评
  • React中路由的参数传递 - 路由的配置文件
  • (附源码)计算机毕业设计SSM基于web的健康饮食信息管理系统
  • 算法的意义、如何学习算法和算法的复杂度
  • 由浅到深带你详谈Java实现数组扩容的三种方式【建议收藏】
  • 【ML on Kubernetes】第 1 章:机器学习的挑战
  • 技巧分享-电脑版微信如何登录多个账号
  • 精品微信小程序springboot居家养老服务+后台管理前后分离
  • GBase 8c 系统表之DB4AI.SNAPSHOT
  • 高频故障-文件扩展名消失(windows)
  • 冲突域与广播域(详解 + 区别)
  • 国庆征文获奖名单公布
  • java毕业设计大学生创新创业项目管理Mybatis+系统+数据库+调试部署
  • Mysql在可重复读事务隔离级别下怎么解决幻读的
  • 【数据结构Java版】链表之单链表的实现
  • C++的RAII思想以及在智能指针上的应用
  • #include <iostream> 和#include <iostream.h>
  • 【硬件开源电路】STM32G070RBT6开发板