【Linux】学习-深入了解文件的读与写

深入了解语言级别(C语言)文件操作的"读"与"写"

在学习前,我们先要知道在Linux下的一个原则:一切皆是文件

如何理解呢?举个外设的例子,比如键盘和显示器,这两个外设也可以其实本质上也是文件,通过与内存的交互来交换信息,而交互的过程其实就是"读"与"写"的过程。而键盘和显示器这两个文件是会默认被打开的

所以想要理解读与写,也就是对文件操作,那就必须得从内存的角度去看待问题:

  1. 从“人”的角度看,人读书写字,这个过程其实就是,书通过文字来传达出信息,人读取信息后,并记录文字在纸上。人读书其实就是向人大脑进行的一个输入知识的过程,这个过程称为“读”,人记录信息文字在纸上,也就是人大脑向纸进行输出的过程,这个过程称为“写”。
  2. 从“内存”的角度看,以显示器和键盘这两个文字为例,键盘就好比书上的文字,内存读取键盘时,就相当于人读取信息的过程,相对于内存而言,这是一种输入,人通过键盘向内存传达信息,也就是内存输入信息的过程,也就是“读”。而内存向显示器上打印文字的过程,就好比人在纸上写字的过程,这是内存对外的一个输出过程,也就是“写”。

因此,从内存的角度来看问题的话,一切都简单起来了:

键盘无外乎就是一种“读”:对应C/C++就是:scanf,cin,是input:输入的过程

显示器无外乎就是一种“写”:对应C/C++就是:printf,cout,是output:输出的过程

这样我们再来看看:什么是文件呢?

文件:站在系统的角度,能够被input或者output写出的设备就叫文件!!

狭义上的文件:普通磁盘文件。

广义上的文件:显示器,键盘,网卡,声卡,显卡,磁盘,几乎所有的外设,都可以称为文件!

语言级文件读写操作函数

学习完这个小知识,接下来就来看看文件读写操作的相关语言级别的函数:

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

fgetc和fputc

int fputc( int c, FILE *stream );
int fgetc( FILE *stream );

image-20230908115511407

image-20230908115440177

fputc是一种写操作,属于输出流,能够向指定文件种写入一个char类型,可以理解成:char put file(字符放入文件),若失败则返回EOF

fgetc是一种读操作,属于输入流,能够读取指定文件的一个字符,若读取失败,则返回EOF

代码演示:

int main()
{//以键盘显示器为例://键盘显示器是默认打开的文件,因此不用进行open和close操作int ch=0;while((ch=fgetc(stdin))!=EOF){fputc(ch,stdout);}return 0;
}

fgets 和 fputs

int fputs( const char *string, FILE *stream );
char *fgets( char *s, int size, FILE *stream );

image-20230908185646783

image-20230908185627656

fputs 和 fgets 类似于fputc 和 fgetc

fputs 是一种写操作,属于输出流,能够向指定文件种写入一个string类型,可以理解成:char put string(字符串放入文件,但不包括 ‘\0’ ),若失败则返回EOF

fgets 是一种读操作,属于输入流,能够读取指定文件中至多比size大小小1的字符串然后将他放入指定的buffer,若提前遇到EOF文件末尾或者 ‘\n’ 则读取提前终止,‘\n’ 也会被读入,读入完成后将自动填充 ‘\0’ 。若读取成功则返回s字符串,失败或者什么都没读取到则返回NULL

代码示例:

int main()
{//以键盘显示器为例://键盘显示器是默认打开的文件,因此不用进行open和close操作char buffer[64];while((fgets(buffer,sizeof buffer,stdin)!=NULL)){fputs(buffer,stdout);}return 0;
}

image-20230909134927998

fscanf 和 fprintf

int fscanf(FILE *stream,const char *format,...);
int fprintf(FILE *stream,const char *format,...);

fscanf文档介绍:

The scanf() family of functions scans input according to format as described below. This format may contain conversion specifications; the results from such conversions, if any, are stored in the locations pointed to by the pointer arguments that follow format. Each pointer argument must be of a type that is appropriate for the value returned by the corresponding conversion specification.

If the number of conversion specifications in format exceeds the number of pointer arguments, the results are undefined. If the number of pointer arguments exceeds the number of conversion specifications, then the excess pointer arguments are evaluated, but are otherwise ignored. These functions return the number of input items successfully matched and assigned, which can be fewer than provided for, or even zero in the event of an early matching
failure. The value EOF is returned if the end of input is reached before either the first successful conversion or a matching failure occurs. EOF is also returned if a read error
occurs, in which case the error indicator for the stream (see ferror(3)) is set, and errno is set indicate the error.

fprintf文档介绍:

The functions in the printf() family produce output according to a format as described below. fprintf() write output to the given output stream;Upon successful return, these functions return the number of characters printed
(excluding the null byte used to end output to strings).If an output error is encountered, a negative value is returned.

fscanf 是一种 ”读” 操作,属于一种输入流,他可以向指定的文件中读取信息并放入格式化参数中, 但若读取的信息大于格式化参数的大小,则结果就不被定义,读取成功则返回读取的信息的数量,失败则返回EOF

fprintf 是一种 “写” 操作,属于一种输出流,他可以向指定文件中写入指定的格式化参数,写入成功则返回写入的char类型的数量但不包括 ’\0‘ ,如果失败则返回一个负值

他们两个的用法其实跟scanf和printf一致,只不过需要指定对应的文件流,而scanf和printf则默认第一个参数为stdin和stdout。

代码示例:

int main()
{//以键盘显示器为例://键盘显示器是默认打开的文件,因此不用进行open和close操作char s[20];while(fscanf(stdin,"%s",&s)!=EOF)fprintf(stdout,"%s\n",s);return 0;
}

注意格式化的使用方法,遇到空格就代表一个占位符的读取已经读取完毕,若空格后还有单词且没有新的占位符就不会进行读入。

fwrite和fread

size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
size_t fwrite(const void *ptr, size_t size, size_t nmemb,FILE *stream);                     

image-20230909151414123

image-20230909153937160

fwrite 是一种 “写” 操作,属于输出流,可以从内存中指定位置的数据中取出数据向指定文件中写入基本单位大小为size,个数为nmemb个size单位的数据(包括二进制数据),若写入成功则返回实际写入的基本单位的个数

fread 是一种 “读” 操作,属于输入流,可以从指定文件中读取基本单位大小为size,个数为nmemb个size单位的数据(包括二进制数据)放入被指向的内存位置中,若读取成功则返回实际读取的基本单位的个数

int main()
{FILE* fp=fopen("log.txt","w");if(fp==NULL){perror("fopen");}const char* s1="hello fwrite\n";fwrite(s1,strlen(s1),1,fp);if(fwrite){fwrite(s1,strlen(s1),1,stdout);}fclose(fp);return 0;
}

image-20230909155547356

";
fwrite(s1,strlen(s1),1,fp);
if(fwrite)
{
fwrite(s1,strlen(s1),1,stdout);
}
fclose(fp);
return 0;
}


[外链图片转存中...(img-GPl5d72L-1707560962937)]

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

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

相关文章

Qt Windows和Android使用MuPDF预览PDF文件

文章目录 1. Windows MuPDF编译2. Android MuPDF编译3. 引用 MuPDF 库4. 解析本地PDF文件 1. Windows MuPDF编译 使用如下命令将MuPDF的源码克隆到本地 git clone --recursive git://git.ghostscript.com/mupdf.git直接用VS,打开 mupdf/platform/win32/mupdf.sln …

docker 部署 mongodb 集群【建议收藏】

一、简洁搭建mognodb副本集 环境说明 我都是在云服务器上搭建的,CentOS7,Docker环境,版本忘记了。我就直接在同一台服务器上搭建三个mongodb即可。 1、基本信息如下 服务器地址 www.it307.top 副本集名称 rs 容器节点及端口映射 ​ m0…

数据结构——6.1 图的基本概念

第六章 图 6.1 图的基本概念 概念 图的概念:G由点集V和边集E构成,记为G(V,E),边集可以为空,但是点集不能为空 注意:线性表可以是空表,树可以是空树,但图不可以是空,即V一定是非空集…

leetcode:63.不同路径二

dp数组含义:由初始位置到最终位置路径个数 递推公式:如果没有障碍再进行递推公式 初始化:1.若起始位置和终止位置有障碍路径个数为0 2.dp[i][0] 1和dp[0][j] 1的for循环条件都需要加上一个and dp[i][0] 0和and dp[0][j] 0. 3.遍历顺序…

案例:三台主机实现 级联复制

介绍:级联复制架构 级联复制架构 是一种特殊的主从结构,之前聊到的几种主从结构都只有两层,但级联复制架构中会有三层,关系如下: 也就是在级联复制架构中,存在两层从库,这实际上属于一主多从架…

Deepin基本环境查看(九)【被封印的创世神】

文章目录 - 相关文章目录1、概述2、Deepin中的创世神和管理员1)创世神root2)root被封印原因3)其他的神灵【管理员】 3、神殿管理【su与sudo】1)su(Switch User)2)sudo(Superuser Do&…

Open CASCADE学习|环形弹簧建模

目录 Draw Test Harness: C: 环形弹簧,也称为弓簧,是由拉伸弹簧和连接弹簧构成的。在结构上,环形弹簧通常包括端环、外环和内环,其主要参数包括弹簧的内径、外径和自由高度。环形弹簧的一个显著特点是&am…

计算机毕业设计SSM基于的冷链食品物流信息管理系统

项目运行 环境配置: Jdk1.8 Tomcat7.0 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。 项目技术: vue mybatis Maven mysql5.7或8.0等等组成,B…

网络原理(一)

💕"Echo"💕 作者:Mylvzi 文章主要内容:网络原理(一) 一. 应用层 应用层是和程序员联系最密切的一层,对于应用层来说,程序员可以自定义应用层协议,应用层的协议一般要约定好以下两部分内容: 根据需求,明确要传输哪些信…

[算法学习]

矩阵乘法 只有当左矩阵列数等于右矩阵行数,才能相乘N*M的矩阵和M*K的矩阵做乘法后矩阵大小为N*k矩阵乘法规则:第一个矩阵A的第 i 行与第二个矩阵的第 j 列的各M个元素对应相乘再相加得到新矩阵C[i][j]的值 整除 同余 同余的性质 线性运算,…

Android:Cordova,JavaScript操作设备功能

Cordova学习 Cordova提供了一组设备相关的API,通过这组API,移动应用能够以JavaScript访问原生的设备功能,如摄像头、麦克风等。 Cordova还提供了一组统一的JavaScript类库,以及为这些类库所用的设备相关的原生后台代码。 Cordova是PhoneGap贡献给Apache后的开源项目,是从…

最适合新手的SpringBoot+SSM项目《苍穹外卖》实战—(一)项目概述

黑马程序员最新Java项目实战《苍穹外卖》,最适合新手的SpringBootSSM的企业级Java项目实战。 项目简介 《苍穹外卖》项目的定位是一款为餐饮企业(餐厅、饭店)定制的软件产品。该项目是一个在线外卖订购系统,顾客可以通过网站或者…

Java安全 CC链1分析(Lazymap类)

Java安全 CC链1分析 前言CC链分析CC链1核心LazyMap类AnnotationInvocationHandler类 完整exp: 前言 在看这篇文章前,可以看下我的上一篇文章,了解下cc链1的核心与环境配置 Java安全 CC链1分析 前面我们已经讲过了CC链1的核心ChainedTransf…

TestNG基础教程

TestNG基础教程 一、常用断言二、执行顺序三、依赖测试四、参数化测试1、通过dataProvider实现2、通过xml配置(这里是直接跑xml) 五、testng.xml常用配置方式1、分组维度控制2、类维度配置3、包维度配置 六、TestNG并发测试1、通过注解来实现2、通过xml来…

Makefile编译原理 make 中的路径搜索_2

一.make中的路径搜索 VPATH变量和vpath关键字同时指定搜索路径。 实验1 VPATH 和 vpath 同时指定搜索路径 mhrubuntu:~/work/makefile1/18$ tree . ├── inc │ └── func.h ├── main.c ├── makefile ├── src1 │ └── func.c └── src2 └── func.c mak…

【正在更新】从零开始认识语音识别:DNN-HMM混合系统语音识别(ASR)原理

摘要 | Abstract TO-BE-FILLED 1.前言 | Introduction 近期想深入了解语音识别(ASR)中隐马尔可夫模型(HMM)和深度神经网络-隐马尔可夫(DNN-HMM)混合模型,但是尽管网络上有许多关于DNN-HMM的介绍,如李宏毅教授的《深度学习人类语言处理》[1],…

火车可视化调车系统

列车在调车作业时,当机车头在尾部推动车厢时,司机室一人操控机车,车厢前端配备两名挂梯随车运行调车员,调车员人为分析行车方向是否有障碍、轨道行人等紧急情况,通过对讲机通知司机控制停车。由于司机无法直观观察列车…

逆向实战29——某度 某家号2024旋转验证码识别

前言 本文章中所有内容仅供学习交流,抓包内容、敏感网址、数据接口均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关,若有侵权,请联系我立即删除! 目标网站 aHR0cHM6Ly9hd…

Linux下的文件权限与访问控制:守护你的数据宝藏

引言 在Linux这片广袤的领域中,文件权限与访问控制犹如守护宝藏的魔法阵,它们确保你的系统安全、数据不被窥探。对于初学者而言,了解并掌握这些魔法阵的奥秘,是成为一名合格Linux巫师的必经之路。那么,就让我们一起揭…

Redis核心技术与实战【学习笔记】 - 28.Redis 6.0新特性(多线程、客户端缓存与安全)

简述 Redis 6.0 新增了几个关键新特性,分别是面向网络处理的多 IO 线程、客户端缓存、细粒度的权限控制,以及 RESP 3 协议的使用。 其中,面向网络处理的多 IO 线程可以提高网络请求处理的速度,而客户端缓存可以让应用直接在客户…