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

【落羽的落羽 C语言篇】文件操作

在这里插入图片描述

文章目录

  • 一、文件的概念和分类
    • 1. 概念和分类
    • 2. 文件名
    • 3. 数据文件
  • 三、文件操作
    • 1. 文件的打开和关闭
      • 1.1 流
      • 1.2 文件指针
      • 1.3 文件的打开和关闭
    • 2. 文件的顺序读写
    • 3. 文件的随机读写
    • 4. 文件读取的判定
    • 5. 文件缓冲区

一、文件的概念和分类

1. 概念和分类

文件是用来保存数据的。如果没有文件,我们写的程序会直接存储在电脑内存中,如果程序退出,内存被释放回收,数据就丢失了。所以如果要将数据进行持久化的保存,我们就可以使用文件来保存数据。
在生活中,我们一般直接将电脑磁盘中的文件称之为文件。而在程序设计中,我们所说的文件一般分为两种:程序文件、数据文件。

  • 程序文件包括:源程序文件(后缀为.c)、目标文件(Windows环境下后缀为.obj)、可执行程序(后缀为.exe)以后会再次介绍的。
  • 数据文件的内容,是程序运行时读写的数据,包括程序运行时需要从中读取数据的文件,或者输出内容的文件。

在之前C语言的学习过程中,我们对数据的输出输入都是以终端为对象的,即从终端的键盘输入数据,运行结果显示到显示器上。但有时候我们也需要把数据输出到磁盘中,也需要从磁盘中读取数据到内存中来使用,这时就是对磁盘里的文件进行文件操作了。

2. 文件名

我们还要知道的是:一个文件通常要有一个唯一的文件标识以便于使用者识别和引用,这就是文件名,通常包含“文件路径、文件名主干、文件后缀”三部分。
举个例子,在我的电脑磁盘中有:
在这里插入图片描述右键点击复制文件地址,能得到这个文件的文件名是:
D:\ACG电吉\春日影\Final春日影 吉他.pdf
其中,这个文件本身的名字“Final春日影 吉他”,是文件名主干。
前面的“D:\ACG电吉\春日影\”,是文件路径。
最后的“.pdf”,是文件后缀。

很简单对吧。

3. 数据文件

数据文件还可以再分为文本文件和二进制文件。

  • 文本文件:数据以ASCII值的形式存储的文件
  • 二进制文件:数据以二进制的形式存储的文件

字符型数据一律用ASCII值形式存储,数值型数据既可以用ASCII值形式存储也可以用二进制形式存储。
它们的区别是什么呢?举个栗子,整数12345

  • 如果以ASCII形值式输出到磁盘中,则占用五个字节(一个字符占据一个字节),内容是00110001 00110010 00110011 00110100 00110101(即ASCII值49、50、51、52、53,对应字符“1”、“2”、“3”、“4”、“5”)
  • 如果以二进制形式输出到磁盘中,则占用四个字节(int大小),内容是00000000 00000000 00110000 00111001(就是12345的二进制表示)

在这里插入图片描述

三、文件操作

1. 文件的打开和关闭

1.1 流

流是计算机领域一个抽象但重要的概念。
简单来说,程序需要跟各种外部设备交互,外部设备包括键盘、显示器、磁盘、U盘、网络等等,程序的数据需要输出到各种外部设备上,也需要从各种外部设备获取数据,不同的外部设备的输入输出操作各不相同。为了方便程序员对各种设备的操作,人们抽象出了“流”的概念。“流”就像一条流淌着数据的河,程序和外部设备将数据都投入这条“河”中,或者各取所需的数据。C语言内部处理好外部设备和流的数据传递,而程序设计者只要再考虑程序如何与流交互就好了。
一般情况下,我们想要往流里写数据,或者从流里读取数据,都是先打开流,然后再操作。

那么,为什么我们以前写C语言程序,从键盘上读取数据,向屏幕上输出数据,并没有打开流的操作呢?这是因为C语言程序在启动时,默认会打开三个流:

  • stdin(标准输入流):它在大多数环境下能从键盘输入数据,scanf函数就是从这个流中读取数据的
  • stdout(标准输出流):它在大多数环境下能输出数据至显示器界面,printf函数就是将信息输出到这个流中的
  • stderr(标准错误流):它在大多数环境下能输出数据至显示器界面

这三个流的类型是FILE*,被称为文件指针。在C语言中,就是通过文件指针来维护流的各种操作的。

1.2 文件指针

每个被使用的文件都在内存中开辟了一个相应的文件信息区,用来存放文件的相关信息,比如文件的名字、状态、位置等等。这些信息被保存在一个结构体变量中,该结构体变量是由系统声明的,被typedef重命名为FILE。不同的C编译器的FILE类型包含的内容不完全相同,但是大同小异。
使用者打开一个文件时,系统会根据文件的情况自动创建一个FILE类型的变量,自动填充好内部信息,使用者不必关心具体细节。
为了维护这个FILE结构的变量,一般使用FILE*类型的指针,这就是文件指针。比如,定义一个FILE* pf;可以使pf指向某个文件的文件信息区,通过该文件信息区的信息来操作该文件,换句话说,通过文还指针能够间接找到与它相关联的文件。

1.3 文件的打开和关闭

读写文件之前应该先打开文件,使用后应该关闭文件。ANSI C规定使用fopen函数打开文件,fclose函数关闭文件。它们(和以下函数)包括在头文件stdio.h中
在这里插入图片描述在这里插入图片描述fclose的使用方式很简单,参数就是需要关闭的文件的文件指针。

fopen的使用较为复杂:

FILE* fopen(const char* filename, const char* mode);

它的返回值是打开的文件的文件指针。
它的第一个参数是文件名,第二个参数是文件的打开模式,有以下模式及其作用:

文件打开模式含义如果指定文件不存在
r(只读)为了输入数据,打开一个文本文件返回空指针
w(只写)为了输出数据,打开一个文本文件创建一个新的文件(如果文件存在,会清空原内容)
a(追加)向文本文件尾添加数据创建一个新的文件
rb(只读)为了输入数据,打开一个二进制文件返回空指针
wb(只写)为了输出数据,打开一个二进制文件创建一个新的文件
ab(追加)向二进制文件尾添加数据创建一个新的文件
r+(读写)为了读写数据,打开一个文本文件返回空指针
w+(读写)为了读写数据,打开一个文本文件创建一个新的文件
a+(读写)在文本文件尾读写数据创建一个新的文件
rb+(读写)为了读写数据,打开一个二进制文件返回空指针
wb+(读写)为了读写数据,创建一个二进制文件创建一个新的文件
ab+(读写)在二进制文件尾读写数据创建一个新的文件

举例,一开始我的项目文件夹里没有data.txt这个文件
如果有FILE* pf = fopen("data.txt","r");在这里插入图片描述

如果是FILE* pf = fopen("data.txt","w");就会在这个代码项目的文件夹中创建这样一个文件:
在这里插入图片描述
当然,我们还可能需要从电脑的其他磁盘上的其他文件中读写数据,就需要明白绝对路径和相对路径的表示方法:

  • 绝对路径就是一个文件的完整文件名,比如之前提到过的 D:\ACG电吉\春日影\Final春日影 吉他.pdf
  • 相对路径要用...表示,.表示当前路径,..表示上一级路径。每一级中间本来需要用\分割,但在C语言中需要被转义,即要用转义字符\\表示\

举个栗子,我的电脑中一开始没有data.txt这个文件,我的C语言程序源文件位置如下:
在这里插入图片描述

如果在程序中以w模式打开一个D盘文件data.txt,就会自动创建

  • 用绝对路径表示:fopen("D:\\data.txt","w");
  • 用相对路径表示:fopen(".\\..\\..\\..\\..\\data.txt","w");
    在这里插入图片描述

都是成功的

2. 文件的顺序读写

文件的顺序读写涉及到一系列函数:

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

这些函数的使用大同小异,我们就举两个例子,其余大家自己查阅了解即可

在这里插入图片描述fputs函数的第一个参数是要写入的字符串,第二个参数是要写进的文件

在这里插入图片描述fgetc函数的参数是要从中读取字符的文件

#include<stdio.h>
int main()
{FILE* pf = NULL;pf = fopen("data.txt", "w");fputs("TECH OTAKUS SAVE THE WORLD", pf);fclose(pf);pf = fopen("data.txt", "r");int n = 0;while(n++ < 5)printf("%c\n", fgetc(pf));fclose(pf);return 0;
}

结果很显然,程序创建了一个文本文件写入了一些内容,然后打印出前四个字符。
在这里插入图片描述在这里插入图片描述

3. 文件的随机读写

上面的函数只能对文件内容按顺序读写,有时我们也需要对内容按照特定顺序读写,这就是文件的随机读写。要用到以下函数:

  • fseek
    在这里插入图片描述这个函数能改变文件光标的位置,“文件光标”就是读写数据的位置,可以理解成我们在电脑手机上打字的这个光标。
    在这里插入图片描述

    第一个参数是文件指针,第二个参数是你想要的偏移量,第三个参数是你想从哪个位置计算偏移量。第三个参数是有三个取值的:在这里插入图片描述SEEK_SET是文件的开头,SEEK_CUR是当前光标的位置,SEEK_END是文件的末尾。
    光标位置是怎么决定的呢?比如文件指针pf刚刚进行了写数据,其指向的文件里刚写下了abcdef,此时光标在末尾,即f后的位置。如果有fseek(pf, 2, SEEK_SET);光标在文本开头后偏移2个位置,即b和c中间。假如我们再写一次数据,就会从这里开始写,新写入的数据会覆盖掉刚才的几个字符:在这里插入图片描述偏移量负值代表左偏移,正值代表右偏移。所以,对于abcdeffseek(pf, 2, SEEK_SET)fseek(pf, -4, SEEK_END)的效果其实是一样的

    再举例一个用法,fgetc读取字符是从文件开头向后一个一个读的。因为光标起始位置是开头,每次读光标之后的一个字符,然后光标向右偏移1。但我们不想按这样的顺序读数据时,就可以用fseek函数实时调整光标的位置了。

  • ftell在这里插入图片描述很简单,它的参数是文件指针,这个函数能返回这个文件中当前光标相对于开头的偏移量

  • rewind在这里插入图片描述这个函数能让参数文件的光标返回起始位置

4. 文件读取的判定

不同的函数读取到文件末尾时的标识不一样,比如fgets读取结束会返回NULL,fgetc读取结束会返回EOF,等等。对于二进制文件,fread的返回值小于实际要读取的个数,说明读取结束

5. 文件缓冲区

最后一个简单的知识点:ASNI C标准采用“缓冲文件系统”处理数据文件,它指系统自动在内存中为程序每一个正在使用的文件开辟一块“文件缓冲区”。从内存向磁盘输出数据,会先送到文件缓冲区,装满缓冲区后才一起送到磁盘上。如果从磁盘向计算机输入数据,则从磁盘文件中读取数据输入到内存缓冲区,然后再从缓冲区逐个地将数据送到程序数据区。缓冲区的大小由C编译系统决定。因为由缓冲区的存在,所以C语言在进行文件操作时,需要刷新缓冲区或者结束时关闭文件。如果不做,可能有读写文件的问题。

在这里插入图片描述
本篇完,感谢阅读~

相关文章:

【落羽的落羽 C语言篇】文件操作

文章目录 一、文件的概念和分类1. 概念和分类2. 文件名3. 数据文件 三、文件操作1. 文件的打开和关闭1.1 流1.2 文件指针1.3 文件的打开和关闭 2. 文件的顺序读写3. 文件的随机读写4. 文件读取的判定5. 文件缓冲区 一、文件的概念和分类 1. 概念和分类 文件是用来保存数据的。…...

RNN之:LSTM 长短期记忆模型-结构-理论详解-及实战(Matlab向)

0.前言 递归&#xff01;循环神经网络Recurrent Neural Network 循环神经网络&#xff08;又称递归神经网络&#xff0c;Recurrent Neural Network&#xff0c;RNN&#xff09;。是一种用于处理序列数据的神经网络结构&#xff0c;具有记忆功能&#xff0c;能够捕捉序列中的时…...

战略与规划方法——深入解析波士顿矩阵(BCG Matrix):分析产品组合的关键工具

深入解析波士顿矩阵(BCG Matrix):分析产品组合的关键工具 在现代商业管理中,合理地分析和管理产品组合对于企业的成功至关重要。波士顿矩阵(BCG Matrix),又称为成长份额矩阵,是一种由波士顿咨询集团(Boston Consulting Group)在20世纪70年代提出的战略工具,用于帮助…...

【记录52】el-table-column 添加fixed属性 滚动条无法滑动

问题&#xff1a; el-table-column 添加fixed属性 滚动条无法滑动 使用element UI组件&#xff0c;用到el-table的el-table-column的fixed属性时&#xff0c;当滚动条长度小于固定列时&#xff0c;滚动条无法通过鼠标去点击滑动操作 原因 fixed是用来固定列的属性&#xff0c;其…...

晨辉面试抽签和评分管理系统之十:如何搭建自己的数据库服务器,使用本软件的网络版

晨辉面试抽签和评分管理系统&#xff08;下载地址:www.chenhuisoft.cn&#xff09;是公务员招录面试、教师资格考试面试、企业招录面试等各类面试通用的考生编排、考生入场抽签、候考室倒计时管理、面试考官抽签、面试评分记录和成绩核算的面试全流程信息化管理软件。提供了考生…...

主链和Layer2之间资产转移

主链和Layer2之间资产转移 主链和Layer2之间资产转移是实现Layer2技术的关键环节,以下是资产转移的流程、流行解决方案及原理: 资产从主链转移到Layer2 用户在主链上发起一笔交易,将资产发送到一个特定的智能合约地址,这个合约是主链与Layer2之间的桥梁。智能合约会锁定用…...

麒麟操作系统服务架构保姆级教程(十)rewrite跳转

如果你想拥有你从未拥有过的东西&#xff0c;那么你必须去做你从未做过的事情 我们访问一个网页的时候会遇到一些奇形怪状的url地址&#xff0c;想优化一下&#xff0c;看着顺眼一点&#xff0c;或者打开一个短视频软件想摸鱼刷一会视频&#xff0c;在打开界面的时候无意间按到…...

MySQL表的创建实验

创建并使用数据库mydb6_product 。 mysql> create database mydb6_product; Query OK, 1 row affected (0.01 sec)mysql> use mydb6_product; Database changed 新建employees表。 对于gender&#xff0c;有默认值意味着不为空&#xff0c;在建表时可以选择不写not nul…...

【高可用自动化体系】自动化体系

架构设计的愿景就是高可用、高性能、高扩展、高效率。为了实现架构设计四高愿景&#xff0c;需要实现自动化系统目标&#xff1a; 标准化。 流程自助化。 可视化&#xff1a;可观测系统各项指标、包括全链路跟踪。 自动化&#xff1a;ci/cd 自动化部署。 精细化&#xff1a…...

总结SpringBoot项目中读取resource目录下的文件多种方法

系列文章目录 提示&#xff1a;这里可以添加系列文章的所有文章的目录&#xff0c;目录需要自己手动添加 例如&#xff1a;第一章 Python 机器学习入门之pandas的使用 提示&#xff1a;写完文章后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目…...

Java-KMP字符串匹配算法

给两个字符串s和t&#xff0c;如何很快的知道s是否包含t&#xff08;即t是否是s的子串&#xff09;。暴力的方法&#xff0c;我们依次以s每个位置为头&#xff0c;去匹配t。 public int find(String s, String t) {char[] ss s.toCharArray();char[] tt t.toCharArray();int …...

Vue3使用vue-count-to数字滚动模块报错解决方案

小伙伴们是不是遇到了vue3项目使用vue-count-to出现报错的问题 报错如下&#xff1a; TypeError: Cannot read properties of undefined (reading _c) 这个错误信息具体是说没读取到_c的属性 具体不清楚是什么原因&#xff0c;排查还得去看源码&#xff0c;所以我们来解决&a…...

【高阶数据结构】线段树加乘(维护序列)详细解释乘与加懒标记

文章目录 1.题目[AHOI2009] 维护序列 2.懒标记处理先加后乘的形式1. 先加后乘的操作 先乘后加的形式2. 先乘后加的操作**乘法操作****加法操作** 懒标记的下传 3.代码 1.题目 题目来源:https://www.luogu.com.cn/problem/P2023 [AHOI2009] 维护序列 题目背景 老师交给小可可…...

replaceState和vue的router.replace删除query参数的区别

使用history.replaceState /*** 替换当前的 history state和url* param {(searchParams:URLSearchParams)>any} cb*/ export const replaceUrlSearch (cb) > {// 获取当前 URLconst url new URL(window.location.href)// 获取 URL 的查询参数const searchParams new …...

[USACO14JAN] Ski Course Rating G

题目大意 滑雪场用一个 N ∗ M N*M N∗M 的整数矩阵表示海拔高度&#xff0c;每个整数表示一个范围在 1 0 9 10^9 109 的高度。每个格子都可以滑到相邻的格子&#xff0c;爱好者们将会在雪场种尽情享受。有些格子被指定为起点&#xff0c;每个起点都要进行评级以帮助爱好者选…...

初步认识 Neo4j 图数据库

Neo4j 是一种高性能的图数据库管理系统&#xff0c;基于图论设计&#xff0c;能够高效地存储和查询复杂的关系数据。以下是关于 Neo4j 的详细介绍&#xff1a; 核心特性 数据模型&#xff1a; Neo4j 使用图数据模型&#xff0c;将数据以节点&#xff08;Node&#xff09;、关系…...

Qt中容器 QVector、QList、QSet和QMap 性能与用途比较

表格汇总&#xff1a; 容器存储结构随机访问性能插入/删除性能主要用途QVector连续存储的动态数组 O ( 1 ) O(1) O(1)末尾&#xff1a; O ( 1 ) O(1) O(1)&#xff0c;中间&#xff1a; O ( n ) O(n) O(n)频繁随机访问&#xff0c;末尾元素的添加/删除QList优化存储&#xff0…...

ASP.NET Core - 依赖注入(四)

ASP.NET Core - 依赖注入&#xff08;四&#xff09; 4. ASP.NET Core默认服务5. 依赖注入配置变形 4. ASP.NET Core默认服务 之前讲了中间件&#xff0c;实际上一个中间件要正常进行工作&#xff0c;通常需要许多的服务配合进行&#xff0c;而中间件中的服务自然也是通过 Ioc…...

数学用语中 up to 的含义

1. 问题 在数学用语中&#xff0c;常见到“up to”这种用法&#xff0c; 但这种用法与我们常规情况下的用法不同&#xff0c;常令人困惑。 2. “等价关系”说明 已知两个数学对象 a 和 b&#xff0c;以及实数域R&#xff0c; • 当 a 和 b是通过 R 关联的&#xff0…...

Spring Boot + MyBatis-Flex 配置 ProxySQL 的完整指南

✅ Spring Boot MyBatis-Flex 配置 ProxySQL 的完整指南 下面是一个详细的教程&#xff0c;指导您如何在 Spring Boot 项目中使用 MyBatis-Flex 配置 ProxySQL 进行 读写分离 和 主从同步 的数据库访问。 &#x1f3af; 目标 在 Spring Boot 中连接 ProxySQL。使用 MyBatis-…...

WEB攻防-通用漏洞_XSS跨站_权限维持_捆绑钓鱼_浏览器漏洞

目录 XSS的分类 XSS跨站-后台植入Cookie&表单劫持 【例1】&#xff1a;利用beef或xss平台实时监控Cookie等凭据实现权限维持 【例2】&#xff1a;XSS-Flash钓鱼配合MSF捆绑上线 【例3】&#xff1a;XSS-浏览器网马配合MSF访问上线 XSS的分类 反射型&#xff08;非持久…...

人工智能任务20-利用LSTM和Attention机制相结合模型在交通流量预测中的应用

大家好&#xff0c;我是微学AI&#xff0c;今天给大家介绍一下人工智能任务20-利用LSTM和Attention机制相结合模型在交通流量预测中的应用。交通流量预测在现代城市交通管理中是至关重要的一环&#xff0c;它对优化交通资源分配以及提升道路通行效率有着不可忽视的意义。在实际…...

Day04-后端Web基础——Maven基础

目录 Maven课程内容1. Maven初识1.1 什么是Maven?1.2 Maven的作用1.2.1 依赖管理1.2.2 项目构建1.2.3 统一项目结构 2. Maven概述2.1 Maven介绍2.2 Maven模型2.2.1 构建生命周期/阶段(Build lifecycle & phases)2.2.2 项目对象模型 (Project Object Model)2.2.3 依赖管理模…...

Hive SQL必刷练习题:留存率问题

首次登录算作当天新增&#xff0c;第二天也登录了算作一日留存。可以理解为&#xff0c;在10月1号登陆了。在10月2号也登陆了&#xff0c;那这个人就可以算是在1号留存 今日留存率 &#xff08;今日登录且明天也登录的用户数&#xff09; / 今日登录的总用户数 * 100% 解决思…...

虚拟同步机(VSG)Matlab/Simulink仿真模型

虚拟同步机控制作为原先博文更新的重点内容&#xff0c;我将在原博客的基础上&#xff0c;再结合近几年的研究热点对其内容进行更新。Ps&#xff1a;VSG相关控制方向的simulink仿真模型基本上都搭建出来了&#xff0c;一些重要的控制算法也完成了实验验证。 现在搭建出来的虚拟…...

单头注意力机制(SHSA)详解

定义与原理 单头注意力机制是Transformer模型中的核心组件之一,它通过模拟人类注意力选择的过程,在复杂的输入序列中识别和聚焦关键信息。这种方法不仅提高了模型的性能,还增强了其解释性,使我们能够洞察模型决策的原因。 单头注意力机制的工作流程主要包括以下几个步骤:…...

【漏洞分析】DDOS攻防分析

0x00 UDP攻击实例 2013年12月30日&#xff0c;网游界发生了一起“追杀”事件。事件的主角是PhantmL0rd&#xff08;这名字一看就是个玩家&#xff09;和黑客组织DERP Trolling。 PhantomL0rd&#xff0c;人称“鬼王”&#xff0c;本名James Varga&#xff0c;某专业游戏小组的…...

JavaScript动态渲染页面爬取之Splash

Splash是一个 JavaScript渲染服务,是一个含有 HTTP API的轻量级浏览器,它还对接了 Python 中的 Twisted 库和 OT库。利用它&#xff0c;同样可以爬取动态渲染的页面。 功能介绍 利用 Splash&#xff0c;可以实现如下功能&#xff1a; 异步处理多个网页的渲染过程:获取渲染后…...

慧集通(DataLinkX)iPaaS集成平台-系统管理之UI库管理、流程模板

UI库管理 UI库管理分为平台级和自建两种&#xff0c;其中平台级就是慧集通平台自己内置的一些ui库所有客户均可调用&#xff0c;自建则是平台支持使用者自己根据规则自己新增对应的UI库。具体界面如下&#xff1a; 自建UI库新增界面&#xff1a; 注&#xff1a;平台级UI库不支…...

OpenCV相机标定与3D重建(59)用于立体相机标定的函数stereoCalibrate()的使用

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 标定立体相机设置。此函数找到两个相机各自的内参以及两个相机之间的外参。 cv::stereoCalibrate 是 OpenCV 中用于立体相机标定的函数。它通过一…...