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

通讯录文件操作化

宝子,你不点个赞吗?不评个论吗?不收个藏吗?

最后的最后,关注我,关注我,关注我,你会看到更多有趣的博客哦!!!

喵喵喵,你对我真的很重要。

目录

使用文件的原因

文件是什么

文件名

通讯录(文件操作化)

修改后的源码

保存数据

加载文件信息到通讯录

总结


使用文件的原因

我们前面学习结构体时,写了通讯录的程序,当通讯录运行起来的时候,可以给通讯录中增加、删除数 据,此时数据是存放在内存中,当程序退出的时候,通讯录中的数据自然就不存在了,等下次运行通讯 录程序的时候,数据又得重新录入,如果使用这样的通讯录就很难受。

我们在想既然是通讯录就应该把信息记录下来,只有我们自己选择删除数据的时候,数据才不复存在。 这就涉及到了数据持久化的问题,我们一般数据持久化的方法有,把数据存放在磁盘文件、存放到数据 库等方式。

使用文件我们可以将数据直接存放在电脑的硬盘上,做到了数据的持久化。


文件是什么

磁盘上的文件是文件。

但是在程序设计中,我们一般谈的文件有两种:程序文件数据文件(从文件功能的角度来分类的)。

程序文件

包括源程序文件(后缀为.c),目标文件(windows环境后缀为.obj),可执行程序(windows环境 后缀为.exe)。

数据文件

文件的内容不一定是程序,而是程序运行时读写的数据,比如程序运行需要从中读取数据的文件, 或者输出内容的文件


文件名

一个文件要有一个唯一的文件标识,以便用户识别和引用。

文件名包含3部分:文件路径+文件名主干+文件后缀


通讯录(文件操作化)

修改后的源码

//Contact.c
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
#include"contact.h"
//静态
//void InitContact(Contact* pc)
//{
//	assert(pc);
//	pc->sz = 0;
//	memset(pc->data, 0, sizeof(pc->data));
//}
void InitContact(Contact* pc)
{assert(pc);pc->sz = 0;PeoInfo* ptr = (PeoInfo*)calloc(sizeof(PeoInfo), DEFAULT_SZ);if (ptr == NULL){perror("InitContact::calloc");return;}pc->data = ptr;pc->capacity = DEFAULT_SZ;//加载文件信息到通讯录LoadContact(pc);
}
//void AddContact(Contact* pc)
//{
//	assert(pc);
//	if (pc->sz == 1000)
//	{
//		printf("通讯录已满,无法添加\n");
//		return;
//	}
//	//增加一个人的信息
//	printf("请输入名字:>");
//	scanf("%s", pc->data[pc->sz].name);
//	printf("请输入年龄:>");
//	scanf("%d", &(pc->data[pc->sz].age));
//	printf("请输入性别:>");
//	scanf("%s", pc->data[pc->sz].sex);
//	printf("请输入地址:>");
//	scanf("%s", pc->data[pc->sz].addr);
//	printf("请输入电话:>");
//	scanf("%s", pc->data[pc->sz].tele);
//	pc->sz++;
//}
void check_capacity(Contact* pc)
{if (pc->sz == pc->capacity){//增加容量PeoInfo* ptr = (PeoInfo*)realloc(pc->data, (pc->capacity + 2) * sizeof(PeoInfo));if (ptr == NULL){perror("check_capacity::realloc");return;}pc->data = ptr;pc->capacity += INC_SZ;printf("增容成功\n");}
}
void AddContact(Contact* pc)
{assert(pc);check_capacity(pc);if (pc->sz == pc->capacity){//增加容量}//增加一个人的信息printf("请输入名字:>");scanf("%s", pc->data[pc->sz].name);printf("请输入年龄:>");scanf("%d", &(pc->data[pc->sz].age));printf("请输入性别:>");scanf("%s", pc->data[pc->sz].sex);printf("请输入地址:>");scanf("%s", pc->data[pc->sz].addr);printf("请输入电话:>");scanf("%s", pc->data[pc->sz].tele);pc->sz++;
}
void ShowContact(const Contact* pc)
{assert(pc);int i = 0;printf("%-20s\t%-4s\t%-5s\t%-20s\t%-15s\n", "名字", "年龄", "性别", "地址", "电话");for (i = 0; i < pc->sz; i++){printf("%-20s\t%-4d\t%-5s\t%-20s\t%-15s\n", pc->data[i].name, pc->data[i].age, pc->data[i].sex, pc->data[i].addr, pc->data[i].tele);}}int FindByName(const Contact* pc, char name[])
{assert(pc);int i = 0;for (i = 0; i < pc->sz; i++){if (strcmp(pc->data[i].name, name) == 0){return i;}}return -1;
}void DelContact(Contact* pc)
{assert(pc);char name[NAME_MAX] = { 0 };if (pc->sz == 0){printf("通讯录为空,无法删除");return;}//删除//找出要删除的人printf("请输入要删除的人的名字;>");scanf("%s", name);int ret = FindByName(pc, name);if (-1 == ret){printf("要删除的人不存在\n");return;}int i = 0;int del = 0;for (i = 0; i < pc->sz; i++){if (strcmp(pc->data[i].name, name) == 0){del = i;break;}}//删除for (i = del; i < pc->sz; i++){pc->data[i] = pc->data[i + 1];}pc->sz--;printf("删除成功\n");
}void SearchContact(const Contact* pc)
{assert(pc);char name[NAME_MAX] = { 0 };printf("请输入要查找人的名字:>");scanf("%s", name);int pos = FindByName(pc, name);if (-1 == pos){printf("要查找的人不存在\n");return;}//打印信息printf("%-20s\t%-4s\t%-5s\t%-20s\t%-15s\n", "名字", "年龄", "性别", "地址", "电话");printf("%-20s\t%-4d\t%-5s\t%-20s\t%-15s\n", pc->data[pos].name, pc->data[pos].age, pc->data[pos].sex, pc->data[pos].addr, pc->data[pos].tele);
}void ModifyContact(Contact* pc)
{assert(pc);char name[NAME_MAX] = { 0 };printf("请输入要删除的人的名字;>");scanf("%s", name);int pos = FindByName(pc, name);if (-1 == pos){printf("要删除的人不存在\n");return;}printf("请输入名字:>");scanf("%s", pc->data[pos].name);printf("请输入年龄:>");scanf("%d", &(pc->data[pos].age));printf("请输入性别:>");scanf("%s", pc->data[pos].sex);printf("请输入地址:>");scanf("%s", pc->data[pos].addr);printf("请输入电话:>");scanf("%s", pc->data[pos].tele);printf("修改完成\n");
}//排序函数//1.按照姓名进行排序
int Conpare_ByName(const void* e1, const void* e2)
{return strcmp(((struct PeoInfo*)e1)->name, ((struct PeoInfo*)e2)->name);
}
//2.按照年龄进行排序
int Conpare_ByAge(const void* e1, const void* e2)
{return ((struct PeoInfo*)e1)->age - ((struct PeoInfo*)e2)->age;
}
//3.按照住址进行排序
int Conpare_ByAddress(const void* e1, const void* e2)
{return strcmp(((struct PeoInfo*)e1)->addr, ((struct PeoInfo*)e2)->addr);
}
void SortContact(Contact* pc)
{assert(pc);printf("请选择你想排序的方式:\n");printf("1.姓名\n2.年龄\n3.住址\n");int input = 0;scanf("%d", &input);switch (input){case 1:qsort(pc->data, pc->sz, sizeof(pc->data[0]), Conpare_ByName);printf("排序成功\n");break;case 2:qsort(pc->data, pc->sz, sizeof(pc->data[0]), Conpare_ByAge);printf("排序成功\n");break;case 3:qsort(pc->data, pc->sz, sizeof(pc->data[0]), Conpare_ByAddress);printf("排序成功\n");break;}
}//void DeaContact(Contact* pc)
//{
//	assert(pc);
//	memset(pc->data, 0, sizeof(pc->data));
//	pc->sz == 0;
//	printf("清空成功!\n");
//
//}
void DestoryContact(Contact* pc)
{free(pc->data);pc->data = NULL;pc->sz = 0;pc = NULL;
}
void SaveContact(Contact* pc)
{//写数据//打开文件FILE* pf = fopen("contact.txt", "wb");if (NULL == pf){perror("SaveContact");}else{int i = 0;for (i = 0; i < pc->sz; i++){fwrite(pc->data + i, sizeof(PeoInfo), 1, pf);}fclose(pf);pf = NULL;printf("保存数据成功\n");}}void LoadContact(Contact* pc)
{//读数据//打开文件FILE*pf=fopen("contact.txt","rb");if (pf == NULL){perror(LoadContact);}else{//2.读数据PeoInfo tmp = { 0 };int i = 0;while (fread(&tmp, sizeof(PeoInfo), 1, pf)){//增容check_capacity(pc);pc->data[i] = tmp;pc->sz++;i++;}fclose(pf);pf = NULL;}
}
//teat.c
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include"contact.h"
void menu()
{printf("*********************************\n");printf("*****   1.add     2.del    ******\n");printf("*****   3.search  4.modify ******\n");printf("*****   5.show    6.sort   ******\n");printf("*****   7.dea     0.exit   ******\n");printf("*********************************\n");
}
int main()
{int input = 0;//ͨѶ¼PeoInfo  data[1000];int sz = 05l;Contact con;InitContact(&con);do{menu();printf("请输入->");scanf("%d", &input);switch (input){case  1:AddContact(&con);break;case  2:DelContact(&con);break;case  3:SearchContact(&con);break;case  4:ModifyContact(&con);break;case  5:ShowContact(&con);break;case  6:SortContact(&con);break;case  7:/*DeaContact(&con);*/DestoryContact(&con);break;case  0://先保存数据SaveContact(&con);DestoryContact(&con);printf("退出通讯录\n");break;default:printf("选择错误\n");break;}} while (input);return 0;
}
//Contact.h
#pragma once
#define MAX 1000
#define NAME_MAX 20
#define SEX_MAX 5
#define ADDR_MAX 30
#define TELE_MAX 12#include<stdio.h>
#include<string.h>
#include<assert.h>
#include<stdlib.h>#define DEFAULT_SZ 3//默认大小
#define INC_SZ 2//人的信息
typedef struct PeoInfo
{char name[NAME_MAX];int age;char sex[SEX_MAX];char addr[ADDR_MAX];char tele[TELE_MAX];
}PeoInfo;struct contact
{struct PeoInfo data[NAME_MAX];int sz;//记录当前已经有的元素个数
};
//静态
//typedef struct Contact
//{
//	PeoInfo data[1000];//存放人的信息
//	int sz;//当前已存放信息的个数
//}Contact;
//动态 
typedef struct Contact
{PeoInfo* data;//指向存放人的信息int sz;//当前已存放信息的个数int  capacity;//当前通讯录最大容量
}Contact;
//初始化通讯录
void InitContact(Contact* pc);
//销毁通讯录
void DestoryContact(Contact* pc);
删除所有联系人
//void DeaContact(Contact* pc);
//增加联系人
void AddContact(Contact* pc);
//删除指定联系人
void DelContact(Contact* pc);
//显示通讯录
void ShowContact(const Contact* pc);
//查找指定联系人
void SearchContact(Contact* pc);
//修改指定联系人
void ModifyContact(Contact* pc);
//联系人排序
void SortContact(Contact* pc);
//保存通讯录中的信息到文件中去
void SaveContact(Contact* pc);
//加载文件信息到通讯录
void LoadContact(Contact* pc);

保存数据

 记得头文件声明和test里引用哈!

 

void SaveContact(Contact* pc)
{//写数据//打开文件FILE* pf = fopen("contact.txt", "wb");if (NULL == pf){perror("SaveContact");}else{int i = 0;for (i = 0; i < pc->sz; i++){fwrite(pc->data + i, sizeof(PeoInfo), 1, pf);}fclose(pf);pf = NULL;printf("保存数据成功\n");}}


加载文件信息到通讯录

void LoadContact(Contact* pc)
{//读数据//打开文件FILE*pf=fopen("contact.txt","rb");if (pf == NULL){perror(LoadContact);}else{//2.读数据PeoInfo tmp = { 0 };int i = 0;while (fread(&tmp, sizeof(PeoInfo), 1, pf)){//增容check_capacity(pc);pc->data[i] = tmp;pc->sz++;i++;}fclose(pf);pf = NULL;}
}

总结

考完试,再复习时,重新更新,抱歉抱歉,罪过,罪过。

宝子,你不点个赞吗?不评个论吗?不收个藏吗?

最后的最后,关注我,关注我,关注我,你会看到更多有趣的博客哦!!!

喵喵喵,你对我真的很重要。

相关文章:

通讯录文件操作化

宝子&#xff0c;你不点个赞吗&#xff1f;不评个论吗&#xff1f;不收个藏吗&#xff1f; 最后的最后&#xff0c;关注我&#xff0c;关注我&#xff0c;关注我&#xff0c;你会看到更多有趣的博客哦&#xff01;&#xff01;&#xff01; 喵喵喵&#xff0c;你对我真的很重…...

为什么 Web3 社交将超越其 Web2 同行

我们最近听到了很多关于 web3 社交媒体平台的消息。但如果你没有跟上&#xff0c;你可能想知道为什么我们已经有了 Twitter、Facebook、Instagram 等&#xff0c;我们还需要 web3 社交。好吧&#xff0c;这一切都取决于谁拥有权力。 在 web2 中&#xff0c;权力掌握在寻求收入最…...

当资深程序员深夜去“打劫”会发生什么?——打家劫舍详解

文章目录一、前言二、概述三、打家劫舍第一晚四、打家劫舍第二晚五、打家劫舍第三晚......一、前言 大家好久不见&#xff0c;正如标题所示&#xff0c;今天我不打算聊一些枯燥的算法理论&#xff0c;我们来聊一聊程序员有多厉害&#xff01; 注意&#xff01;&#xff01;&am…...

linux 线程

文章目录1、线程的概念1.1、进程 vs 线程1.2、线程的种类2、线程的控制2.1、线程的创建2.2、线程的退出2.3、线程的取消2.4、线程的等待2.5、线程的分离2.5、线程清理函数线程清理函数响应的时机线程清理函数不响应的时机3、线程的同步和互斥3.1、锁机制3.1.1、锁的类型3.1.2、…...

Windows 安装appium环境

1 windows Appium环境 1.1 安装Node.js Node.js的安装相对简单,下载安装包安装&#xff08;安装包node-v19.6.0-x64.msi&#xff09;, nodejs 安装 然后一路狂点下一步就可以了 安装完成后,在终端中输入node -v,显示版本号则表示安装成功 node-v16.13.1 1.2 JDK安装及环境变…...

为什么要在电子产品中使用光耦合器?

介绍 光耦合器不仅可以保护敏感电路&#xff0c;还可以使工程师设计各种硬件应用。光耦合器通过保护元件&#xff0c;可以避免更换元件的大量成本。然而&#xff0c;光耦合器比保险丝更复杂。光耦合器还可以通过光耦合器连接和断开两个电路&#xff0c;从而方便地控制两个电路…...

Vue3 如何实现一个函数式右键菜单(ContextMenus)

前言: 最近在公司 PC 端的项目中使用到了右键出现菜单选项这样的一个工作需求&#xff0c;并且自己现在也在实现一个偶然迸发的 idea&#xff08; 想用前端实现一个 windows 系统从开机到桌面的 UI&#xff09;&#xff0c;其中也要用到右键弹出菜单这样的一个功能&#xff0c;…...

ffmpeg转码转封装小工具开发

如下图所示&#xff0c;是本人开发的一个转码转封装小工具 其中目标文件视频编码格式支持&#xff1a;H264&#xff0c;H265&#xff0c;VP8&#xff0c;VP9。 目标文件封装格式支持&#xff1a;mp4,mkv,avi,mov,flv。 目标文件音频编码格式支持两个&#xff0c;COPY和AAC&am…...

重入和线程安全

在整个文档中&#xff0c;重入和线程安全用于标记类和函数&#xff0c;从而表明怎样在多线程应用中使用它们。 线程安全函数可以从多个线程同时调用&#xff0c;即使调用使用共享数据也是如此&#xff0c;因为对共享数据的所有引用都是序列化的。也可以从多个线程同时调用重入…...

MySQL数据库06——条件查询(WHERE)

MySQL条件查询&#xff0c;主要是对数据库里面的数据按照一定条件进行筛选&#xff0c;主要依靠的是WHERE语句进行。 先来了解一下基础的条件运算。 关系运算符 逻辑运算符 逻辑运算符优先级&#xff1a;NOT>AND>OR&#xff0c;关系运算符>逻辑运算符 SQL特殊运算符…...

Lesson 6.5 机器学习调参基础理论与网格搜索

文章目录一、机器学习调参理论基础1. 机器学习调参目标及基本方法2. 基于网格搜索的超参数的调整方法2.1 参数空间2.2 交叉验证与评估指标二、基于 Scikit-Learn 的网格搜索调参1. sklearn 中网格搜索的基本说明2. sklearn 中 GridSearchCV 的参数解释3. sklearn 中 GridSearch…...

leetcode: Two Sum

leetcode: Two Sum1. 题目1.1 题目描述2. 解答2.1 baseline2.2 基于baseline的思考2.3 优化思路的实施2.3.1 C中的hashmap2.3.2 实施2.3.3 再思考2.3.4 最终实施3. 总结1. 题目 1.1 题目描述 Given an array of integers nums and an integer target, return indices of the …...

共享模型之无锁(三)

1.原子累加器 示例代码: public class TestAtomicAdder {public static void main(String[] args) {for (int i 0; i < 5; i) {demo(() -> new AtomicLong(0),(adder) -> adder.getAndIncrement());}for (int i 0; i < 5; i) {demo(() -> new LongAdder(),(…...

微信小程序 Springboot校运会高校运动会管理系统

3.1小程序端 小程序登录页面&#xff0c;用户也可以在此页面进行注册并且登录等。 登录成功后可以在我的个人中心查看自己的个人信息或者修改信息等 在广播信息中我们可以查看校运会发布的一些信息情况。 在首页我们可以看到校运会具体有什么项目运动。 在查看具体有什么活动我…...

走进独自开,带你轻松干副业

今天给大家分享一个开发者的福利平台——独自开&#xff08;点击直接注册&#xff09;&#xff0c;让你在家就能解决收入问题。 文章目录一、平台介绍二、系统案例三、获取收益四、使用平台1、用户注册2、用户认证3、任务报价五、文末总结一、平台介绍 简单说明 独自开信息科技…...

SpringBoot+Vue实现师生健康信息管理系统

文末获取源码 开发语言&#xff1a;Java 框架&#xff1a;springboot JDK版本&#xff1a;JDK1.8 服务器&#xff1a;tomcat7 数据库&#xff1a;mysql 5.7/8.0 数据库工具&#xff1a;Navicat11 开发软件&#xff1a;eclipse/myeclipse/idea Maven包&#xff1a;Maven3.3.9 浏…...

数据库第四章节第三次作业内容

1、显示所有职工的基本信息。 2、查询所有职工所属部门的部门号&#xff0c;不显示重复的部门号。 3、求出所有职工的人数。 4、列出最高工和最低工资。 5、列出职工的平均工资和总工资。 6、创建一个只有职工号、姓名和参加工作的新表&#xff0c;名为工作日期表…...

一篇五分生信临床模型预测文章代码复现——FIgure 9.列线图构建,ROC分析,DCA分析 (四)

之前讲过临床模型预测的专栏,但那只是基础版本,下面我们以自噬相关基因为例子,模仿一篇五分文章,将图和代码复现出来,学会本专栏课程,可以具备发一篇五分左右文章的水平: 本专栏目录如下: Figure 1:差异表达基因及预后基因筛选(图片仅供参考) Figure 2. 生存分析,…...

神经网络实战--使用迁移学习完成猫狗分类

前言&#xff1a; Hello大家好&#xff0c;我是Dream。 今天来学习一下如何使用基于tensorflow和keras的迁移学习完成猫狗分类&#xff0c;欢迎大家一起前来探讨学习~ 本文目录&#xff1a;一、加载数据集1.调用库函数2.加载数据集3.数据集管理二、猫狗数据集介绍1.猫狗数据集介…...

Attention机制 学习笔记

学习自https://easyai.tech/ai-definition/attention/ Attention本质 Attention&#xff08;注意力&#xff09;机制如果浅层的理解&#xff0c;跟他的名字非常匹配。他的核心逻辑就是“从关注全部到关注重点”。 比如我们人在看图片时&#xff0c;对图片的不同地方的注意力…...

网络六边形受到攻击

大家读完觉得有帮助记得关注和点赞&#xff01;&#xff01;&#xff01; 抽象 现代智能交通系统 &#xff08;ITS&#xff09; 的一个关键要求是能够以安全、可靠和匿名的方式从互联车辆和移动设备收集地理参考数据。Nexagon 协议建立在 IETF 定位器/ID 分离协议 &#xff08;…...

Ubuntu系统下交叉编译openssl

一、参考资料 OpenSSL&&libcurl库的交叉编译 - hesetone - 博客园 二、准备工作 1. 编译环境 宿主机&#xff1a;Ubuntu 20.04.6 LTSHost&#xff1a;ARM32位交叉编译器&#xff1a;arm-linux-gnueabihf-gcc-11.1.0 2. 设置交叉编译工具链 在交叉编译之前&#x…...

Java 语言特性(面试系列1)

一、面向对象编程 1. 封装&#xff08;Encapsulation&#xff09; 定义&#xff1a;将数据&#xff08;属性&#xff09;和操作数据的方法绑定在一起&#xff0c;通过访问控制符&#xff08;private、protected、public&#xff09;隐藏内部实现细节。示例&#xff1a; public …...

大型活动交通拥堵治理的视觉算法应用

大型活动下智慧交通的视觉分析应用 一、背景与挑战 大型活动&#xff08;如演唱会、马拉松赛事、高考中考等&#xff09;期间&#xff0c;城市交通面临瞬时人流车流激增、传统摄像头模糊、交通拥堵识别滞后等问题。以演唱会为例&#xff0c;暖城商圈曾因观众集中离场导致周边…...

pam_env.so模块配置解析

在PAM&#xff08;Pluggable Authentication Modules&#xff09;配置中&#xff0c; /etc/pam.d/su 文件相关配置含义如下&#xff1a; 配置解析 auth required pam_env.so1. 字段分解 字段值说明模块类型auth认证类模块&#xff0c;负责验证用户身份&am…...

高频面试之3Zookeeper

高频面试之3Zookeeper 文章目录 高频面试之3Zookeeper3.1 常用命令3.2 选举机制3.3 Zookeeper符合法则中哪两个&#xff1f;3.4 Zookeeper脑裂3.5 Zookeeper用来干嘛了 3.1 常用命令 ls、get、create、delete、deleteall3.2 选举机制 半数机制&#xff08;过半机制&#xff0…...

MMaDA: Multimodal Large Diffusion Language Models

CODE &#xff1a; https://github.com/Gen-Verse/MMaDA Abstract 我们介绍了一种新型的多模态扩散基础模型MMaDA&#xff0c;它被设计用于在文本推理、多模态理解和文本到图像生成等不同领域实现卓越的性能。该方法的特点是三个关键创新:(i) MMaDA采用统一的扩散架构&#xf…...

Matlab | matlab常用命令总结

常用命令 一、 基础操作与环境二、 矩阵与数组操作(核心)三、 绘图与可视化四、 编程与控制流五、 符号计算 (Symbolic Math Toolbox)六、 文件与数据 I/O七、 常用函数类别重要提示这是一份 MATLAB 常用命令和功能的总结,涵盖了基础操作、矩阵运算、绘图、编程和文件处理等…...

JVM暂停(Stop-The-World,STW)的原因分类及对应排查方案

JVM暂停(Stop-The-World,STW)的完整原因分类及对应排查方案,结合JVM运行机制和常见故障场景整理而成: 一、GC相关暂停​​ 1. ​​安全点(Safepoint)阻塞​​ ​​现象​​:JVM暂停但无GC日志,日志显示No GCs detected。​​原因​​:JVM等待所有线程进入安全点(如…...

智能分布式爬虫的数据处理流水线优化:基于深度强化学习的数据质量控制

在数字化浪潮席卷全球的今天&#xff0c;数据已成为企业和研究机构的核心资产。智能分布式爬虫作为高效的数据采集工具&#xff0c;在大规模数据获取中发挥着关键作用。然而&#xff0c;传统的数据处理流水线在面对复杂多变的网络环境和海量异构数据时&#xff0c;常出现数据质…...