文件操作介绍及C语言实现通讯录管理系统3.0最终版(文件操作版本)

文章目录

  • 1. 前言
  • 2. 文件操作
    • 2.1 什么是文件
    • 2.2 文件缓冲区
    • 2.3 文件指针
    • 2.4 文件的打开与关闭
    • 2.5 文件的顺序读写
  • 3. 优化通讯录
    • 3.1 保存通讯录
    • 3.2 加载通讯录
  • 4. 结尾

1. 前言

上一篇文章我们学习了动态内存开辟的相关知识点,并用动态内存函数优化了我们的通讯录,但通讯录还有需要改进的地方,比如,正常情况下的通讯录,应该可以一直保存联系人信息,而不是退出就清空了,这就需要我们实实在在的保存下来一个通讯录。
接下来我会给大家介绍文件以及如何用C语言来操作文件。

2. 文件操作

2.1 什么是文件

磁盘上的文件是文件。但是在程序设计中,我们一般谈的文件有两种:程序文件、数据文件
程序文件:包括源程序文件(后缀为.c),目标文件(windows环境后缀为.obj),可执行程序(windows环境后缀为.exe)。
数据文件:文件的内容不一定是程序,而是程序运行时读写的数据,比如程序运行需要从中读取数据的文件,或者输出内容的文件。
文件名包含3部分:文件路径+文件名主干+文件后缀
例如:c:\code\test.txt

本文主要讨论的是数据文件。
以前我们处理数据的输入输出都是以终端为对象的,即从终端的键盘输入数据,运行结果显示到显示器上。其实有时候我们会把信息输出到磁盘上,就比如通讯录的保存,当需要的时候再从磁盘上把数据读取到内存中使用,这里处理的就是磁盘上的文件。

2.2 文件缓冲区

ANSIC 标准采用“缓冲文件系统”处理的数据文件的,所谓缓冲文件系统是指系统自动地在内存中为程序中每一个正在使用的文件开辟一块“文件缓冲区”。
从内存向磁盘输出数据会先送到内存中的缓冲区,装满缓冲区后才一起送到磁盘上。
如果从磁盘向计算机读入数据,则从磁盘文件中读取数据输入到内存缓冲区(充满缓冲区),然后再从缓冲区逐个地将数据送到程序数据区(程序变量等)。缓冲区的大小根据C编译系统决定的。

2.3 文件指针

缓冲文件系统中,关键的概念是“文件类型指针”,简称“文件指针”。
每个被使用的文件都在内存中开辟了一个相应的文件信息区,用来存放文件的相关信息(如文件的名字,文件状态及文件当前的位置等)。
这些信息是保存在一个结构体变量中的。该结构体类型是有系统声明的,取名FILE
一般都是通过一个FILE的指针来维护这个FILE结构的变量
FILE* pf;
定义pf是一个指向FILE类型数据的指针变量。可以使pf指向某个文件的文件信息区(是一个结构体变量)。
通过该文件信息区中的信息就能够访问该文件。也就是说,通过文件指针变量能够找到与它关联的文件。

2.4 文件的打开与关闭

文件在读写之前应该先打开文件,在使用结束之后应该关闭文件。
打开:
FILE* fopen(const char* filename, const char* mode); mode是打开方式
关闭:
int fclose(FILE* stream);

文件的打开方式有很多种,这里我给大家一一列举出来供大家参考使用:

文件使用方式               含义                    如果指定文件不存在
“r”(只读) 为了输入数据,打开一个已经存在的文本文件    出错
“w”(只写) 为了输出数据,打开一个文本文件             建立一个新的文件
“a”(追加) 向文本文件尾添加数据                       出错
“rb”(只读) 为了输入数据,打开一个二进制文件          出错
“wb”(只写) 为了输出数据,打开一个二进制文件          建立一个新的文件
“ab”(追加) 向一个二进制文件尾添加数据                出错
“r+”(读写) 为了读和写,打开一个文本文件              出错
“w+”(读写) 为了读和写,建议一个新的文件              建立一个新的文件
“a+”(读写) 打开一个文件,在文件尾进行读写            建立一个新的文件
“rb+”(读写) 为了读和写打开一个二进制文件             出错
“wb+”(读写) 为了读和写,新建一个新的二进制文件       建立一个新的文件
“ab+”(读写) 打开一个二进制文件,在文件尾进行读和写   建立一个新的文件

举例使用:

int main()
{
	//打开文件
	FILE* pf = fopen("test.txt", "w");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	//写文件
	int ch = 0;
	fputc('w', pf);

	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}


int main()
{
	//打开文件
	FILE* pf = fopen("test.txt", "r");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	//读文件
	int ch = 0;
	while ((ch = fgetc(pf)) != EOF)
	{
		printf("%c ", ch);
	}
	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

2.5 文件的顺序读写

字符输入函数 – fgetc – 所有输入流
字符输出函数 – fputc – 所有输出流
文本行输入函数 – fgets – 所有输入流
文本行输出函数 – fputs – 所有输出流
格式化输入函数 – fscanf – 所有输入流
格式化输出函数 – fprintf – 所有输出流
二进制输入 – fread – 文件
二进制输出 – fwrite – 文件

3. 优化通讯录

在为大家介绍完文件操作以后,我们就可以来利用文件操作来优化我们的通讯录,使通讯录在每次退出都可以保存到磁盘上的一个文件里,而且每次重新启动的时候都会把这个文件再加载进通讯录中,让我们可以直接打印出所有联系人。

3.1 保存通讯录

利用文件操作来把通讯录里联系人的信息保存在一个txt文件中。

void SaveContact(const contact* pc)
{
	FILE* pf = fopen("contact.dat", "w");
	if (pf == NULL)
	{
		perror("fopen");
		return;
	}
	int i = 0;
	for (i = 0; i < pc->count; i++)
	{
		fprintf(pf, "%s %s %d %s %s", pc->date->name, pc->date->sex, pc->date->age, pc->date->tele, pc->date->address);
	}
	fclose(pf);
	pf = NULL;
}

3.2 加载通讯录

我们需要每次进入程序的时候都自动加载好文件中的联系人信息,所以这个函数可以放在初始化通讯录函数的内部。

void LoadContact(contact* pc)
{
	FILE* pf = fopen("contact.dat", "r");
	if (pf == NULL)
	{
		perror("fopen");
		return;
	}
	people tmp = {0};
	while (fread(&tmp, sizeof(people), 1, pf))
	{
		CheckCapacity(pc);
		pc->date[pc->count] = tmp;
		pc->count++;
	}
	fclose(pf);
	pf = NULL;
}

这样我们就可以永久的保存通讯录里联系人的信息在磁盘上,什么时候打开都能直接打印之前保存好的信息。
例1

4. 结尾

到本文章为止,使用C语言实现通讯录管理系统已经完成全部优化,主要目的是通过这个小程序来学习各种知识,并优化自己的代码,思路才是重中之重,非常感谢大家的耐心阅读,如有问题可以评论区留言或者私信博主,觉得博主写的不错的朋友,可以三连支持一下,感谢各位。

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

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

相关文章

【数据库连接,线程,ThreadLocal三者之间的关系】

一、数据库连接与线程的关系 在实际项目中&#xff0c;数据库连接是很宝贵的资源&#xff0c;以MySQL为例&#xff0c;一台MySQL服务器最大连接数默认是100, 最大可以达到16384。但现实中最多是到200&#xff0c;再多MySQL服务器就承受不住了。因为mysql连接用的是tcp协议&…

JAVA:常用API

一.什么是API&#xff1f; API&#xff08;Application Programming Interface&#xff09;&#xff1a;应用程序编程接口。 简单的来说&#xff1a;就是Java帮我们已经写好的方法&#xff0c;我们可以直接使用。 二.有哪些常用的API&#xff1f; Object、Objects、StringB…

二战华为成功上岸,准备了小半年,要个27k应该也算不上很高吧~

先说下我基本情况&#xff0c;本科不是计算机专业&#xff0c;现在是学通信&#xff0c;然后做图像处理&#xff0c;可能面试官看我不是科班出身没有问太多计算机相关的问题&#xff0c;因为第一次找工作&#xff0c;华为的游戏专场又是最早开始的&#xff0c;就投递了&#xf…

二,八,十,十六进制等常用进制详解

总目录 文章目录总目录一、常用进制1、进制基本信息2、各进制的表示形式二、进制转换原理1、其他进制转为十进制计算原理2、十进制转为其他进制计算原理3、二进制&#xff0c;八进制&#xff0c;十六进制之间的转换结语一、常用进制 1、进制基本信息 基数数码名称描述20 和 1…

【C++】| C/C++内存管理

前言&#xff1a; 在上期&#xff0c;我们已经对类和对象的全部知识进行了总结和梳理。在类和对象学习完之后&#xff0c;今天我将给大家呈现的是关于——C/C内存管理的基本知识。 本文目录 1. C/C内存分布 2. C语言中动态内存管理方式 &#xff08;1&#xff09;C语言跟内…

php科研项目申报审批系统

目 录 1 绪论 4 1.1 开发背景 4 1.2 开发意义 4 1.3 相关知识介绍 4 1.3.1 Apache 4 1.3.2 MySQL 5 1.3.3 PHP 6 1.3.4 Dreamweaver CS3 7 1.4 本文所做的工作及组织结构 7 2 系统分析 7 2.1 需求分析 7 2.2 可行性分析 7 2.3 系统界面…

CSDN博客专家证书发放名单(2023年3月已更新)

目录 证书发放频次 6月&#xff08;第一批&#xff09;证书发放名单&#xff08;80位&#xff09; 7月&#xff08;第二批&#xff09;证书发放名单&#xff08;50位&#xff09; 8月&#xff08;第三批&#xff09;证书发放名单&#xff08;54位&#xff09; 9月&#xf…

2个月月活突破1亿,增速碾压抖音,出道即封神的ChatGPT,现在怎么样了?ChatGPT它会干掉测试?

从互联网的普及到智能手机&#xff0c;都让广袤的世界触手而及&#xff0c;如今身在浪潮中的我们&#xff0c;已深知其力。 前阵子爆火的ChatGPT&#xff0c;不少人保持观望态度。现如今&#xff0c;国内关于ChatGPT的各大社群讨论&#xff0c;似乎沉寂了不少&#xff0c;现在…

Prometheus监控实战之Exporter详解

1 exporter是什么&#xff1f; 广义上向prometheus提供监控数据的程序都可以成为一个exporter的&#xff0c;一个exporter的实例称为target, exporter来源主要2个方面&#xff0c;一个是社区提供的&#xff0c;一种是用户自定义的。 2 常用exporter 官方和一些社区提供好多ex…

彻底关闭Windows自动更新

彻底关闭Windows自动更新 目录 彻底关闭Windows自动更新 前言 Windows10彻底关闭自动更新方法步骤&#xff1a; 一、禁用Windows Update服务 二、在组策略里关闭Win10自动更新相关服务 三、禁用任务计划里边的Win10自动更新 四、在注册表中关闭Win10自动更新 前言 我们用…

易语言支持库配置闪退丨支持库配置崩溃_易语言打开支持库配置就闪退怎么办?

易语言支持库配置闪退打不开怎么办&#xff1f; 易语言支持库配置闪退解决方法丨支持库配置崩溃_易语言打开支持易语言支持库配置闪退丨支持库配置崩溃_易语言打开支持库配置就闪退怎么办? 很多人都遇到过 打开易语言支持库安装菜单报错退出的问题 今天教大家解决方法 我们…

4.2--Redis总结之高可用篇(关于哨兵机制)---(温故而知新篇)--加油呀

1.为什么要有哨兵机制&#xff1f; 在 Redis 的主从架构中&#xff0c;由于主从模式是读写分离的&#xff0c;如果主节点挂了&#xff0c;那么将没有主节点来服务客户端的写操作请求&#xff0c;也没有主节点给从节点进行数据同步了 哨兵机制&#xff0c;它的作用是实现主从节…

spring集成mybaits以注解方式完成连表查询练习

题目&#xff1a; 以注解的方式完成连表查询 1、查询全部员工信息&#xff0c;要求显示部门名称 2、根据姓名模糊查询员工信息 自己看完&#xff0c;建一个简单的员工表和部门表。 1、先创建一个maven模块&#xff0c;这里直接建的普通…

SpringMVC --- 获取请求参数、域对象共享数据、视图

一、SpringMVC获取请求参数 1.1、通过ServletAPI获取 将 HttpServletRequest 作为控制器方法的形参&#xff0c;此时 HttpServletRequest 类型的参数表示封装了当前请求的请求报文的对象 RequestMapping("/param/servletAPI")public String getParamByServletAPI(H…

从零开始实现一个C++高性能服务器框架----配置模块

此项目是根据sylar框架实现&#xff0c;是从零开始重写sylar&#xff0c;也是对sylar丰富与完善 项目地址&#xff1a;https://gitee.com/lzhiqiang1999/server-framework 简介 项目介绍&#xff1a;实现了一个基于协程的服务器框架&#xff0c;支持多线程、多协程协同调度&am…

【C++】多态(下)

文章目录1.单继承中的虚函数表整体代码用程序打印虚表如何寻找到虚表地址虚表存在哪里&#xff1f;2.多继承中的虚函数表整体代码寻找虚表地址注意事项多继承重写后的func1的地为什么地址不同&#xff1f;ptr1调用函数——一次jmpptr2 调用函数——多次jmp1.单继承中的虚函数表…

window环境 python ide 安装教程分享

一、 右键-以管理员身份运行 python.exe&#xff08;以安装 3.8 的为例&#xff0c;安 装方法是一样的哈&#xff09; 二、选择你的安装方式。 特别注意&#xff1a;需要把 Add Python ** to PATH 勾选上 ②Customize installation 是自定义安装&#xff0c;安装位置你可以自己…

链表【左程云:Java】

一、单链表 1.单链表的节点结构 2.反转单向和双向链表 2.1 反转单向 package leetcode.链表;/*** author lin* creat 2022--12--12:50** https://leetcode.cn/problems/reverse-linked-list/*/ public class $_206反转链表 {public class ListNode {int val;ListNode next;L…

基于VHDL语言的汽车测速系统设计_kaic

摘 要 汽车是现代交通工具。车速是一项至关重要的指标。既影响着汽车运输的生产率,又关乎着汽车行驶有没有超速违章&#xff0c;还影响着汽车行驶时人们的人身安全。而伴随着我国国民的安全防范意识的逐步增强&#xff0c;人们也开始越来越关心因为汽车的超速而带来的极其严重…

一份sql笔试

1、 select substr(time,1,10),count(order_id),count(distinct passenger_id) from order where substr(time,1,7)2023-08 group by substr(time,1,10) order by substr(time,1,10);2、 select city_id from (select * from order where substr(time,1,7) 2022-08) t1 left j…