【C语言】23.文件操作

由于要对数据进行持久化保存,我们就有了文件。

一、程序文件与数据文件

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

1.1 程序文件

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

1.2 数据文件

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

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

1.3 文件名

⼀个文件要有⼀个唯⼀的文件标识,以便用户识别和引用。
文件名包含3部分:文件路径+文件名主干+文件后缀
例如: c:\code\test.txt
分为绝对路径和相对路径,为了方便起见,文件标识常被称为文件名。

二、二进制文件与文本文件

根据数据的组织形式,数据文件被称为文本文件或者二进制文件。
数据在内存中以二进制的形式存储,如果不加转换的输出到外存的文件中,就是二进制文件
如果要求在外存上以ASCII码的形式存储,则需要在存储前转换。以ASCII字符的形式存储的文件就是文本文件

⼀个数据在文件中是怎么存储的呢?
字符⼀律以ASCII形式存储,数值型数据既可以用ASCII形式存储,也可以使用二进制形式存储。
如有整数10000,如果以ASCII码的形式输出到磁盘,则磁盘中占用5个字节(每个字符⼀个字节),而二进制形式输出,则在磁盘上只占4个字节。
在这里插入图片描述

三、文件的打开与关闭

3.1 流与标准流

3.1.1流

我们程序的数据需要输出到各种外部设备,也需要从外部设备获取数据,不同的外部设备的输入输出操作各不相同,为了方便程序员对各种设备进行方便的操作,我们抽象出了流的概念,我们可以把流想象成流淌着字符的河。
C程序针对文件、画面、键盘等的数据输入输出操作都是通过流操作的。
⼀般情况下,我们要想向流里写数据,或者从流中读取数据,都是要打开流,然后操作。

3.1.2 标准流

那为什么我们从键盘输入数据,向屏幕上输出数据,并没有打开流呢?

那是因为C语言程序在启动的时候,默认打开了3个流:
• stdin - 标准输入流,在大多数的环境中从键盘输入,scanf函数就是从标准输入流中读取数据。
• stdout - 标准输出流,大多数的环境中输出至显示器界面,printf函数就是将信息输出到标准输出流中。
• stderr - 标准错误流,大多数环境中输出到显示器界面。

这是默认打开了这三个流,我们使用scanf、printf等函数就可以直接进行输入输出操作的。
stdin、stdout、stderr 三个流的类型是: FILE* ,通常称为文件指针。
C语言中,就是通过 FILE* 的文件指针来维护流的各种操作的。

3.2 文件指针

缓冲文件系统中,关键的概念是“文件类型指针”,简称“文件指针”。
每个被使用的文件都在内存中开辟了⼀个相应的文件信息区,用来存放文件的相关信息(如文件的名字,文件状态及文件当前的位置等)。这些信息是保存在⼀个结构体变量中的。该结构体类型是由系统声明的,取名 FILE .
例如,VS2013编译环境提供的 stdio.h 头文件中有以下的文件类型申明:

struct _iobuf 
{
	 char *_ptr;
	 int _cnt;
	 char *_base;
	 int _flag;
	 int _file;
	 int _charbuf;
	 int _bufsiz;
	 char *_tmpfname;
};
typedef struct _iobuf FILE;

不同的C编译器的FILE类型包含的内容不完全相同,但是大同小异。
每当打开⼀个文件的时候,系统会根据文件的情况自动创建⼀个FILE结构的变量,并填充其中的信息,使用者不必关心细节。
⼀般都是通过⼀个FILE的指针来维护这个FILE结构的变量,这样使用起来更加方便。
下面我们可以创建⼀个FILE*的指针变量:

	FILE* pf;//⽂件指针变量

定义pf是⼀个指向FILE类型数据的指针变量。可以使pf指向某个文件的文件信息区(是⼀个结构体变量)。通过该文件信息区中的信息就能够访问该文件。也就是说,通过文件指针变量能够间接找到与它关联的文件
在这里插入图片描述

3.3 文件的打开与关闭

文件在读写之前应该先打开文件,在使用结束之后应该关闭文件。
在编写程序的时候,在打开文件的同时,都会返回⼀个FILE*的指针变量指向该文件,也相当于建立了指针和文件的关系。
ANSI C 规定使用 fopen 函数来打开文件, fclose 来关闭文件。
在这里插入图片描述
在这里插入图片描述
mode表示文件的打开模式,下⾯都是文件的打开模式:

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

四、文件的顺序读写

4.1 顺序读写函数介绍

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

上面的适用于所有输入流⼀般指适用于标准输入流和其他输入流(如文件输入流);所有输出流⼀般指适用于标准输出流和其他输出流(如文件输出流)

4.2 函数对比

函数功能
scanf针对标准输入(键盘)的格式化输入函数
printf针对标准输出(屏幕)的格式化输出函数
fscanf针对所有输入流的格式化输入函数
fprintf针对所有输出流的格式化输出函数
sscanf从一个字符串中读取一个格式化的数据
sprintf把一个格式化的数据转换为字符串

五、文件的随机读写

5.1 fseek

根据文件指针的位置和偏移量来定位文件指针。
在这里插入图片描述
在这里插入图片描述

5.2 ftell

返回文件指针相对于起始位置的偏移量
在这里插入图片描述

5.3 rewind

让文件指针的位置回到文件的起始位置
在这里插入图片描述

六、文件结束的判断

  1. 文本文件读取是否结束,判断返回值是否为 EOF ( fgetc ),或者 NULL ( fgets )
    例如:
    • fgetc 判断是否为 EOF .
    • fgets 判断返回值是否为 NULL .
  2. 二进制文件的读取结束判断,判断返回值是否小于实际要读的个数。
    例如:
    • fread判断返回值是否小于实际要读的个数。

6.1 feof

在文件读取结束后,判断是否是因为遇到文件末尾而结束。
在这里插入图片描述

6.2 ferror

在文件读取结束后,判断是否是因为遇到错误而结束。
在这里插入图片描述

6.3使用的例子

6.3.1文本文件

#include <stdio.h>
#include <stdlib.h>
 
int main(void)
{
	 int c; // 注意:int,⾮char,要求处理EOF 
	 FILE* fp = fopen("test.txt", "r");
	 if(!fp) 
	 {
		 perror("File opening failed");
		 return EXIT_FAILURE;
	 }
	 //fgetc 当读取失败的时候或者遇到⽂件结束的时候,都会返回EOF 
	 while ((c = fgetc(fp)) != EOF) // 标准C I/O读取⽂件循环 
	 { 
		 putchar(c);
	 }
	 //判断是什么原因结束的 
	 if (ferror(fp))
		 puts("I/O error when reading");
	 else if (feof(fp))
		 puts("End of file reached successfully");		 
	 fclose(fp);
	 return 0;
}

6.3.2二进制文件

#include <stdio.h>
 
enum { SIZE = 5 };
int main(void)
{
	 double a[SIZE] = {1.,2.,3.,4.,5.};
	 FILE *fp = fopen("test.bin", "wb"); // 必须⽤⼆进制模式 
	 fwrite(a, sizeof *a, SIZE, fp); // 写 double 的数组 
	 fclose(fp);
	 
	 double b[SIZE];
	 fp = fopen("test.bin","rb");
	 size_t ret_code = fread(b, sizeof *b, SIZE, fp); // 读 double 的数组 
	 if(ret_code == SIZE) 
	 {
		 puts("Array read successfully, contents: ");
		 for(int n = 0; n < SIZE; ++n) 
			 printf("%f ", b[n]);
		 putchar('\n');
	 } 
	 else 
	 { // error handling
		 if (feof(fp))
			 printf("Error reading test.bin: unexpected end of file\n");
		 else if (ferror(fp)) 
			 perror("Error reading test.bin");
	 } 
	 fclose(fp);
}

七、文件缓冲区

ANSIC 标准采用“缓冲文件系统”处理的数据文件的,所谓缓冲文件系统是指系统自动地在内存中为程序中每⼀个正在使用的文件开辟⼀块“文件缓冲区”。从内存向磁盘输出数据会先送到内存中的缓冲区,装满缓冲区后才⼀起送到磁盘上。如果从磁盘向计算机读入数据,则从磁盘文件中读取数据输入到内存缓冲区(充满缓冲区),然后再从缓冲区逐个地将数据送到程序数据区(程序变量等)。缓冲区的大小根据C编译系统决定的。
在这里插入图片描述
因为有缓冲区的存在,C语言在操作文件的时候,需要做刷新缓冲区或者在文件操作结束的时候关闭文件。
如果不做,可能导致读写文件的问题。

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

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

相关文章

pdf压缩,pdf压缩在线网页版,在线压缩pdf网站

在数字化时代&#xff0c;pdf文件已经成为我们工作、学习和生活中不可或缺的一部分。然而&#xff0c;pdf文件往往体积庞大&#xff0c;传输效率低下&#xff0c;还占用大量存储空间。如何在不影响文件质量的前提下&#xff0c;减小pdf文件的大小呢&#xff1f;今天&#xff0c…

线程安全问题(二)——死锁

死锁 前言可重入锁逻辑 两个线程两把锁&#xff08;死锁&#xff09;死锁的特点多个线程多把锁&#xff08;哲学家就餐问题&#xff09;总结 前言 在前面的文章中&#xff0c;介绍了锁的基本使用方式——锁 在上一篇文章中&#xff0c;通过synchronized关键字进行加锁操作&am…

在Stimulsoft 报告中连接来自 MySQL 的数据

Stimulsoft Ultimate &#xff08;原Stimulsoft Reports.Ultimate&#xff09;是用于创建报表和仪表板的通用工具集。该产品包括用于WinForms、ASP.NET、.NET Core、JavaScript、WPF、PHP、Java和其他环境的完整工具集。无需比较产品功能&#xff0c;Stimulsoft Ultimate包含了…

数据结构(Java):迭代器遍历【底层源码解析】

1、引言 我们知道&#xff0c;对于List系列集合&#xff0c;添加的元素是有序、可重复、有索引的&#xff1b;而对于Set系列集合&#xff0c;添加的元素是无序、不重复、无索引的。 那么使用for循环通过下标来对Set系列集合进行遍历&#xff0c;那显然是不行的。 迭代器就可…

docker k8s

1、docker是什么&#xff1f; 将环境和程序一起打包给到 服务器运行的工具软件。 2、基础镜像base image是什么&#xff1f; 操作系统&#xff1a;用户空间、内核空间 阉割操作系统&#xff0c;利用其的用户空间&#xff08;因为应用程序运行在用户空间&#xff09;&#xf…

转换Python2 转 Python3 小程序

转换Python2 -> Python3 藉由python35\Tools\scripts\2to3.py 档转换 python D:\python\Tools\scripts\2to3.py D:\Users\a0979\Desktop\scrip.pypython [转档程式] [欲转档.py] * python 为 python3 ->因为转档程式为python3 ![](https://i.imgur.com/PeQkvhk.png)py…

STM32的EXTI简介

一&#xff0c;EXTI&#xff08;External Interrupt&#xff09;外部中断事件控制器 什么是EXTI&#xff1f; 1.监测指定的GPIO口的电平信号变化&#xff0c;并检测到指定条件时&#xff0c;向内核的中断控制器NVIC发出中断申请。NVIC在裁决后&#xff0c;如果满足条件&#xf…

工业4.0能给电能表带来什么机会

一、技术革新与升级 工业4.0的核心在于智能化和网络化&#xff0c;这促使电能表行业进行技术革新和升级。传统的电能表功能单一&#xff0c;主要用于测量电能消耗。而在工业4.0的推动下&#xff0c;电能表逐渐发展成为集信息储存和处理、网络通信、实时监测等多种功能于一体的…

云计算【第一阶段(22)】Linux的进程和计划任务管理

目录 一、查看进程 1.1、程序和进程的关系 1.2、查看进程 1.2.1、静态查看进程信息ps ​编辑 1.2.1.1、实验 1.2.2、动态查看进程信息top 1.2.2.1、实验 1.2.2.2、top 命令全屏操作界面快捷键 1.2.3、pgrep根据特定条件查询进程pid信息 1.2.4、pstree命令以树形结构列出…

5、Python之rich:GUI之外,终端呈现也能玩出花

引言 在Python系列文章的上一篇中&#xff0c;我们从print的定义出发&#xff0c;进一步探索了print()函数更多的用法&#xff0c;尤其是一些哪怕是Python老手也可能忽略的用法。没有阅读的或者需要回顾print()及输出格式化的扩展用法&#xff0c;可以查看上一篇文章。 虽然pr…

Git安装与使用及整合IDEA使用的详细教程

1. 版本控制软件介绍 版本控制软件提供完备的版本管理功能&#xff0c;用于存储、追踪目录&#xff08;文件夹&#xff09;和文件的修改历史&#xff0c;是软件开发者的必备工具&#xff0c;是软件公司的基础设施。版本控制软件的最高目标&#xff0c;是支持软件公司的配置管理…

Swift 新结构化并发中鲜为人知的 isolated 参数

概述 伴随着 Swift 5.5&#xff08;WWDC21&#xff09;推出的新结构化并发到今年的 WWDC 24 已经有 3 个多年头了。想必大家都对其中 async/awiat、async let、TaskGroup、Actor 等各种概念都了然于胸了吧&#xff1f; 不过小伙伴们可能不知道的是&#xff1a;新结构化并发&a…

【Eplan】P8-图纸设计的四种方法

【更多软件使用问题请点击亿道电子官方网站】 1、 文档目标 了解 EPLAN 的图纸设计的四种方法&#xff1a;面向图形、面向设备、面向物料清单、面向安装情况&#xff1b; 2、 问题场景 为什么 EPLAN 要使用四种不同的设计方法。 3、软硬件环境 1、软件版本&#xff1a;EPLAN…

Ubuntu无法安全地用该源进行更新,所以默认禁用该源。

解决方案 1. 获取并添加缺失的 GPG 公钥 可以使用 apt-key 命令来添加缺失的公钥。根据错误信息&#xff0c;缺失的公钥是 3B4FE6ACC0B21F32。 sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 3B4FE6ACC0B21F322. 更新软件包列表 添加公钥后&#xff0c;更…

ADS131A04硬件设计与软件调试

一、IC基本信息 ADS131A0x 双通道或四通道 24 位 128kSPS 同步采样 Δ-Σ ADC •双通道或四通道同步采样差分输入 • 数据速率&#xff1a;高达 128kSPS • 高性能&#xff1a; – 单通道精度&#xff1a;在 10,000:1 动态范围内优于 0.1% – 有效分辨率&#xff1a;20.6位…

【MotionCap】搭建wsl2的pytorch环境

参考大神:wsl2-ubuntu版本 cuda下周cuda11.3 wget https://developer.download.nvidia.com/compute/cuda/11.3.0/local_installers/cuda_11.3.0_465.19.01_linux.run sudo sh cuda_11.3.0_465.19.01_linux.run cuda是开源的么?下15分钟

重磅!云起无垠荣获“智能模糊测试赛道领航者”等多项殊荣

近日&#xff0c;以 “新质•真能力”&#xff08;新质生产力&#xff0c;安全真能力&#xff09;为主题的第四届数字安全大会正式召开。在此次大会上&#xff0c;数世咨询发布了《中国数字安全产业年度报告(2024)》、新质百强榜单以及国内首本《数字安全蓝皮书》。这些报告和榜…

操作系统精选题(四)(论述题)

&#x1f308; 个人主页&#xff1a;十二月的猫-CSDN博客 &#x1f525; 系列专栏&#xff1a; &#x1f3c0;操作系统 &#x1f4aa;&#x1f3fb; 十二月的寒冬阻挡不了春天的脚步&#xff0c;十二点的黑夜遮蔽不住黎明的曙光 目录 前言 一、银行家算法的一道例题 二、页…

【NOI】C++程序设计入门四

文章目录 前言一、浮点型&#xff08;float和double&#xff09;1.float类型2.double类型 二、保留小数的方法方法一&#xff1a;方法二&#xff1a; 三、样题讲解问题1&#xff1a;1603. 冷饮的价格&#xff1f;问题2&#xff1a;1957. 求三个数的平均数问题3&#xff1a;1602…

爬数据是什么意思?

爬数据的意思是&#xff1a;通过网络爬虫程序来获取需要的网站上的内容信息&#xff0c;比如文字、视频、图片等数据。网络爬虫&#xff08;网页蜘蛛&#xff09;是一种按照一定的规则&#xff0c;自动的抓取万维网信息的程序或者脚本。 学习一些爬数据的知识有什么用呢&#x…