通讯录——文件读写版本

news/2024/5/7 6:09:44/文章来源:https://blog.csdn.net/MDLYB/article/details/127231836

通讯录最终版本——文件读写

  前面在暴躁小猿给大家分享了通讯录的静态版本和动态版本,但是这两个版本都不能实现文件的读写,每次运行程序都不能保存和读取数据,这样的通讯录是不完善的,根本没有办法去使用,所以为了满足需求,我们需要用对文件可以读写的通讯录,出于这个原因,通讯录最终版本就来了


在这里插入图片描述

文章目录

  • 通讯录最终版本——文件读写
  • 一、头文件
  • 二、功能实现模块
    • 1.保存联系人到文件
    • 2.对文件联系人信息的读取
  • 三、测试文件
  • 总结


一、头文件

代码如下(示例):

#define  _CRT_SECURE_NO_WARNINGS 1
#define max 3
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include <windows.h>//初始化通讯录
void inicontact(struct contact* pc);
//添加联系人
void addpeople(struct contact* pc);
//删除联系人
void delpeople(struct contact* pc);
//展示联系人
void showpeople(struct contact* pc);
//查找联系人
void searchpeople(struct contact* pc);
//修改联系人
void revisepeople(struct contact* pc);
//联系人排序
void sortpeople(struct contact* pc);
//清除联系人
void deadpeople(struct contact* pc);
//保存联系人到文件
void savecontact(struct contact* pc);
//加载联系人从文件到内存
void Loadcontact(struct contact* pc);
//判断是否通讯录已满
void check(struct contact* pc);
//比较函数
int cmp(struct contact* pc);struct PeoInfo
{char name[10];char sex[5];int age;char tel[15];char address[20];
};
struct contact
{struct PeoInfo* date;int sz;int max;
};

  我们这个版本的通讯录是在动态版本通讯录的基础上实现的,所以在头文件中我们就只是多了保存联系人信息到文件和读取联系人信息这个两个函数的声明,其余的代码和动态版本通讯录大同小异,如果有不解的地方可以看小猿之前动态版本通讯录的博客,里面有详细讲解。

二、功能实现模块

#define  _CRT_SECURE_NO_WARNINGS 1
#include "FILE.h"
void menu()
{printf("------------------------------------\n");printf("--------请选择你要实现的功能--------\n");printf("--------1.添加联系人信息------------\n");printf("--------2.删除指定联系人信息--------\n");printf("--------3.查找指定联系人信息--------\n");printf("--------4.修改指定联系人信息--------\n");printf("--------5.显示所有联系人信息--------\n");printf("--------6.以名字排序所有联系人------\n");printf("--------0.      退出         ------\n");
}
void check(struct contact* pc)
{if ((pc->sz) >= (pc->max)){pc = (struct PeoInfo*)realloc(pc->date, (pc->max + 2) * sizeof(struct PeoInfo));printf("扩容成功\n");pc->max += 2;}
}
void Loadcontact(struct contact* pc)
{FILE* pf = fopen("contacts.txt", "r");if (pf == NULL){perror("fopen");return;}struct PeoInfo tmp = { 0 };while (fread(&tmp, sizeof(struct PeoInfo), 1, pf)){check(pc);pc->date[pc->sz] = tmp;pc->sz++;}fclose(pf);pf = NULL;
}void inicontact(struct contact* pc){pc->sz = 0;pc->max = 3;pc->date = (struct PeoInfo*)calloc(3, sizeof(struct PeoInfo));Loadcontact(pc);}void addpeople(struct contact* pc){check(pc);printf("请输入姓名\n");scanf("%s", &(pc->date[pc->sz].name));printf("请输入性别\n");scanf("%s", &(pc->date[pc->sz].sex));printf("请输入年龄\n");scanf("%d", &(pc->date[pc->sz].age));printf("请输入电话\n");scanf("%s", &(pc->date[pc->sz].tel));printf("请输入住址\n");scanf("%s", &(pc->date[pc->sz].address));printf("添加联系人完毕\n");pc->sz++;}void delpeople(struct contact* pc){char name1[10];int input1;printf("请输入你要删除的联系人\n");scanf("%s", &name1);int i;for (i = 0; i < (pc->sz); i++){if (strcmp(pc->date[i].name, name1) == 0){printf("查到到联系人%s是否确认删除\n", name1);scanf("%d", &input1);if (input1 == 1){for (int j = i; j < ((pc->sz) - 1); j++){(pc->date[j]) = (pc->date[j + 1]);pc->sz--;}printf("删除成功\n");}else{printf("成功取消\n");}}}if (i >= (pc->sz)){printf("联系人%s不存在\n", name1);}}void searchpeople(struct contact* pc){char name1[10];printf("请输入你要查找的联系人\n");scanf("%s", &name1);int i;for (i = 0; i < (pc->sz); i++){if (strcmp(pc->date[i].name, name1) == 0){printf("%-10s\t %-15s\t %-3s\t %-15s\t %-20s\t\n","name", "sex", "age", "tel", "address");printf("%-10s\t %-15s\t %-3d\t %-15s\t %-20s\t\n",pc->date[i].name,pc->date[i].sex,pc->date[i].age,pc->date[i].tel,pc->date[i].address);}}if (i > pc->sz){printf("不存在此联系人%s\n", name1);}}void revisepeople(struct contact* pc){char name1[10];printf("请输入你要修改的联系人\n");scanf("%s", &name1);int i;for (i = 0; i < (pc->sz); i++){if (strcmp(pc->date[i].name, name1) == 0){printf("请输入姓名\n");scanf("%s", &(pc->date[i].name));printf("请输入性别\n");scanf("%s", &(pc->date[i].sex));printf("请输入年龄\n");scanf("%d", &(pc->date[i].age));printf("请输入电话\n");scanf("%s", &(pc->date[i].tel));printf("请输入住址\n");scanf("%s", &(pc->date[i].address));printf("修改联系人完毕\n");}}if (i > pc->sz){printf("不存在此联系人%s\n", name1);}}void showpeople(struct contact* pc){int i;printf("%-10s\t %-15s\t %-3s\t %-15s\t %-20s\t\n","name", "sex", "age", "tel", "address");for (i = 0; i < (pc->sz); i++){printf("%-10s\t %-15s\t %-3d\t %-15s\t %-20s\t\n",pc->date[i].name,pc->date[i].sex,pc->date[i].age,pc->date[i].tel,pc->date[i].address);}}int cmp(void* e1, void* e2){return strcmp(((struct PeoInfo*)e1)->name, ((struct PeoInfo*)e2)->name);}void sortpeople(struct contact* pc){qsort(pc, pc->sz, sizeof(struct PeoInfo), cmp);}void savecontact(struct contact* pc){FILE* pf = fopen("contacts.txt", "w");if (pf == NULL){perror("fopen");return;}int i = 0;for (i = 0; i < pc->sz; i++){fwrite(pc->date + i, sizeof(struct PeoInfo), 1, pf);}fclose(pf);pf = NULL;}void deadpeople(struct contact* pc){free(pc->date);pc->date = NULL;pc->max = 0;pc->sz = 0;}

  这是我们功能实现总体的代码,也是在动态通讯录上改造的,我们多了两个功能就是保存联系人信息到文件和读取文件中联系人的信息到内存,我们用两个独立的函数来实现这两个功能。

1.保存联系人到文件

代码如下(示例):

	void savecontact(struct contact* pc){FILE* pf = fopen("contacts.txt", "w");if (pf == NULL){perror("fopen");return;}int i = 0;for (i = 0; i < pc->sz; i++){fwrite(pc->date + i, sizeof(struct PeoInfo), 1, pf);}fclose(pf);pf = NULL;}

  我们先对一个contacts.txt文件进行只写操作,如果我们之前没有这个文件系统就会自动创建一个文件,然后我们需要判断一下fopen函数返回的FILE结构的指针是否为NULL,如果为NULL我们就用perror函数显示fopen函数打开错误,如果返回的指针不为NULL,我们就将pc->date内的数据写入到pf这个FILE结构的指针所指向的文件信息区,然后达到写入文件的目的,最后别忘了关闭文件并且将pf指针置为NULL。

2.对文件联系人信息的读取

代码如下(示例):

void check(struct contact* pc)
{if ((pc->sz) >= (pc->max)){pc = (struct PeoInfo*)realloc(pc->date, (pc->max + 2) * sizeof(struct PeoInfo));printf("扩容成功\n");pc->max += 2;}
}
void Loadcontact(struct contact* pc)
{FILE* pf = fopen("contacts.txt", "r");if (pf == NULL){perror("fopen");return;}struct PeoInfo tmp = { 0 };while (fread(&tmp, sizeof(struct PeoInfo), 1, pf)){check(pc);pc->date[pc->sz] = tmp;pc->sz++;}fclose(pf);pf = NULL;
}void inicontact(struct contact* pc){pc->sz = 0;pc->max = 3;pc->date = (struct PeoInfo*)calloc(3, sizeof(struct PeoInfo));Loadcontact(pc);}

  在这里我们为了实现从文件中读取联系人的信息到内存涉及到了三个函数,分别是check函数,它的功能是查询通讯录是否已满,inicontact函数,它的功能是对通讯录进行初始化,我们之前的两个版本都是将创建的空间置为0,但是这里我们要将文件中的信息读入内存中,所以我们要在初始化的时候实现这一功能,Loadcontact函数就是我们加载联系人信息的实现函数,由它来控制加载文件中联系人的信息。
这里的难点在于fread函数,我们先来看一下fread函数的定义:
在这里插入图片描述
  fread函数的作用就是读取文件类型指针所指向空间的count个大小为size的二进制数据放入到ptr的指针所指向的空间中,函数的返回值类型是size_t,也就是无符号整型的数据,如果我们读到一个数据就返回1,两个数据就返回2,所以我们把它写在while循环中作为while循环条件,如果读取结束就返回0,自然会跳出循环。
这就最终实现了通讯录的最终版本——文件读写版本通讯录。

三、测试文件

代码如下(示例):

#define _CRT_SECURE_NO_WARNINGS
#include "FILE.h"
int main()
{struct contact c1;inicontact(&c1);int input = 1;do{menu();scanf("%d", &input);switch (input){case 1:system("cls");addpeople(&c1);break;case 2:system("cls");delpeople(&c1);break;case 3:system("cls");searchpeople(&c1);break;case 4:system("cls");revisepeople(&c1);break;case 5:system("cls");showpeople(&c1);break;case 6:system("cls");sortpeople(&c1);break;case 0:system("cls");savecontact(&c1);free(c1.date);exit(1);break;default:break;}} while (input);return 0;
}

总结

  写到这里通讯录的三个版本也就都结束了,后一个版本都是在前一个版本的基础上改进的,逐步让功能完善,成为可以真正满足需求的通讯录,再大的程序我们都可以大而化小,分而治之,逐步实现它的一个一个功能,希望我的博客对大家有所帮助,我们明天见~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_20755.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java毕设项目在线点餐系统计算机(附源码+系统+数据库+LW)

Java毕设项目在线点餐系统计算机&#xff08;附源码系统数据库LW&#xff09; 项目运行 环境配置&#xff1a; Jdk1.8 Tomcat8.5 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目…

电源芯片的选择

什么是电源芯片?它有什么作用?在选择电源芯片的时候&#xff0c;应该考虑那些地方?输入电压线性调整率、输入电压线性变化时对输出电压的相对影响&#xff1f;下面先来了解几个概念问题&#xff1a; 1、输出电压负载调整率&#xff1a;负载电流变化时输出电压相对变化情况 …

(附源码)计算机毕业设计SSM在线考试主观题评分系统

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

神经网络适用于什么情况,神经网络是分类算法吗

1、人工神经网络评价法 人工神经元是人工神经网络的基本处理单元&#xff0c;而人工智能的一个重要组成部分又是人工神经网络。人工神经网络是模拟生物神经元系统的数学模型&#xff0c;接受信息主要是通过神经元来进行的。首先&#xff0c;人工神经元利用连接强度将产生的信号…

web响应式布局与BootStrap框架

目录什么是响应式网页布局媒体查询什么是媒体查询&#xff1f;媒体类型&#xff08;mediatype&#xff09;关键字媒体特性&#xff08;media feature&#xff09;引入方式BootStrap简介使用步骤栅格系统组件JavaScript插件定制案例腾讯前端web首页什么是响应式网页布局 响应式…

Excel工作日日历

在项目管理中&#xff0c;通常需要制作一个工作日历&#xff0c;能标识出休假日。 难点在识别休假日&#xff0c;不能简单根据周几来判断&#xff0c;而是要根据国家法定假日和换班日进行判断。我做了一个示例&#xff0c;给感兴趣的朋友演示一下。 我会分步骤讲解一下如何制作…

APS高级排产如何帮助帮助企业制定生产计划?

对于物料及产能规划与现场详细作业排程而言&#xff0c;企业常因无法确实掌握生产制造现场实际的产能状况及物料进货时程&#xff0c;而采取有单就接的接单政策与粗估产能的生产排程方式&#xff0c;但又在提高对顾客的服务水平及允诺交期的基本前提下&#xff0c;导致生产车间…

Redis配置文件详解

容量单位不区分大小写&#xff0c;G和GB有区别 可以使用 include 组合多个配置问题 网络配置 日志输出级别 日志输出文件 持久化规则 由于Redis是基于内存的数据库&#xff0c;需要将数据由内存持久化到文件中 持久化方式&#xff1a; RDBAOF RDB文件相关 主从复制 Security模…

【建立逻辑结构】

前言 这是【Windows Server 2016 服务器配置与管理】的一些实操 下面是我自己做实验过程当中的一些简单记录&#xff0c;可能会有小错误&#xff0c;欢迎大家的指正&#xff01; Slogan&#xff1a;日拱一卒&#xff0c;功不唐捐&#xff01;&#xff01;&#xff01; 问答题 …

【重识云原生】第四章云网络6.4.5.2节——Deployment配置详细说明

1 deployment配置说明 1.1 deployment的资源清单文件 主要字段说明&#xff1a; 全量字段说明&#xff1a; apiVersion: apps/v1 #版本号 kind: Deployment #类型 metadata: #元数据 name: #rs名称 namespace: #所属命名空间 labels: #标签 controller: deploy spec: #详…

Linux自动挂载 (autofs)

个人主页&#xff1a;&#x1f497;wei_shuo的个人主页 &#x1f3c0; Hello World &#xff01;&#x1f3c0; 文章目录实现自动挂载-autofsautofs工具简单使用autofs配置详细说明自动挂载资源有两种格式&#xff1a;相对路径挂载法绝对路径挂载法优化 Linux 系统性能安装 Tun…

动态代理详解

想要更加透彻的理解动态代理&#xff0c;首先要熟悉下静态代理 一、静态代理 总结来说&#xff1a;目标类和代理类实现了相同的接口&#xff0c;在代理类中依赖了目标类&#xff0c;代理类的方法中调用了目标类的方法&#xff0c;并做了一些增强性的工作。 1、实现静态代理&…

ROS|乌龟TF变换案例分析

1. 相关源码内容 1.1 turtle_df_demo.launch <launch><!-- Turtlesim Node--><node pkg"turtlesim" type"turtlesim_node" name"sim"/><node pkg"turtlesim" type"turtle_teleop_key" name"tel…

如何快速创建 GCDW 实例

GCDW 实例需云用户注册 GCDW 租户成功后&#xff0c; GBASE 云服务系统给租户分配独 立的实例&#xff0c; 同时创建租户的数据库根用户&#xff0c; 根用户即为该实例的超户&#xff0c; 拥有该实例 的最高权限&#xff0c; 租户可以通过根用户登录自己的实例管理数据&#xf…

Centos7 单机单网卡 RDO 安装 OpenStack

文档 OpenStack 涵盖太多知识量&#xff0c;总是找不到一个称心的官方文档 OpenStack Installation Guide for Red Hat Enterprise Linux and CentOS 这个是中文版的&#xff0c;但是 UPDATED: 2017-06-12 11:14 &#xff0c;很古老了&#xff01;基本概念和思想还是一样的 h…

SiO2/罗丹明B荧光杂化纳米微球/硅钼比核壳结构二氧化硅微球钼酸钙荧光粉的性能

SiO2/罗丹明B荧光杂化纳米微球性能制备&#xff1a; 在甲苯存在下的反相微乳液体系中,将γ-缩水甘油醚氧丙基三甲氧基硅烷(KH560)与罗丹明B进行预反应&#xff1b;再与正硅酸乙酯( TEOS)经原位溶胶-凝胶反应,制备SiO2/罗丹明B荧光杂化纳米微球.通过FTIR、UV-Vis、TEM、TG和光致…

聚焦 | 电力行业国产操作系统迎来大市场,麒麟信安积极承接发展新机遇

近年来&#xff0c;针对信息安全的外部环境不确定性加剧&#xff0c;作为关系到国计民生的电力行业&#xff0c;加速了自主创新的步伐。 从2009年起&#xff0c;电力行业就开始采用拥有自主核心技术的软硬件设施&#xff0c;到如今&#xff0c;整个电力行业已普遍完成了调度自动…

4.<tag-排序和TopK问题的三种典型解法>补充: 面试题 17.14. 最小K个数 + lt.215-数组中的第K个最大元素 dbc

面试题 17.14. 最小K个数 [案例需求] TopK问题很普遍, 解题套路也很简单, 无非就是排序, 运用最基础的排序(如Array.sort(nums))复杂度为nlogn, 或者使用堆, 复杂度为nlogk, 或者在快排的基础上进行减治 详细参见此文: 点我 [思路分析一, 直接排序] 对原数组从小到大排序后取出…

毕业设计 深度学习 机器视觉 车位识别车道线检测 - python opencv

0 前言 &#x1f525; 这两年开始毕业设计和毕业答辩的要求和难度不断提升&#xff0c;传统的毕设题目缺少创新和亮点&#xff0c;往往达不到毕业答辩的要求&#xff0c;这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师的要求。 为了大家能够顺利以及最少的精力通过…

Airflow学习笔记

CSDN话题挑战赛第2期 参赛话题&#xff1a;学习笔记 项目中解决的问题 使用airflow调度hive脚本跑批任务 视频教程上整理知识点 学习视频&#xff1a;https://www.bilibili.com/video/BV1V7411K7Gy?p40&vd_sourceb002288652bae647c598ddf77f79a7b8 Airflow基本概念 Airfl…