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

news2024/10/6 10:28:11

深入了解语言级别(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.coloradmin.cn/o/1443987.html

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

相关文章

springboot+vue电影推荐系统 java电影院售票选座系统1r6m2

用户模块 1)注册:用户输入账号、密码、确认密码、昵称、手机、邮箱、简介,点击注册按钮,完成注册。 2)登录:用户成功输入用户账号和密码,点击登录按钮。 3)用户主页面:以用户登录成功后,可以查看…

基于vue+node.js的校园跳蚤市场系统多商家

校园跳蚤市场系统可以在短时间内完成大量的数据处理、帮助用户快速的查找校园跳蚤市场相关信息,实现的效益更加直观。校园跳蚤市场系统中采用nodejs技术和mysql数据库。主要包括管理员、发布者和用户三大部分,主要功能是实现对个人中心、用户管理、发布者…

机器学习复习(8)——逻辑回归

目录 逻辑函数(Logistic Function) 逻辑回归模型的假设函数 从逻辑回归模型转换到最大似然函数过程 最大似然函数方法 梯度下降 逻辑函数(Logistic Function) 首先,逻辑函数,也称为Sigmoid函数&#…

Peter算法小课堂—单调队列

祝大家新年快乐! 今天这一次有点简单。 单调队列有两个要点,一个是单调,另一个就是我们的队列。 听到队列,我相信大家一定会想到它的好朋友BFS吧。但是……今天……可……没……那么……简单哦。 西佳佳偶像天团1 题目描述 …

M1 Mac使用SquareLine-Studio进行LVGL开发

背景 使用Gui-Guider开发遇到一些问题,比如组件不全。使用LVGL官方的设计软件开发 延续上一篇使用的基本环境。 LVGL项目 新建项目 选择Arduino的项目,设定好分辨率及颜色。 设计UI 导出代码 Export -> Create Template Project 导出文件如图…

1978-2023年全国国内生产总值、分产业分行业增加值相关指标数据

1978-2023年全国国内生产总值、分产业分行业增加值相关指标数据 1、时间:1978-2023年 2、指标:国内生产总值(亿元)、第一产业增加值(亿元)、第二产业增加值(亿元)、第三产业增加值(亿元)、人均国内生产总值(元)、国民总收入指数(上年100)、国内生产总值…

车载电子电器架构 —— 电子电气系统车载功能子系统

车载电子电器架构 —— 电子电气系统车载功能子系统 我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 本就是小人物,输了就是输了&#xff0c…

Linux 从日志中抽取信息,批量生成SQL语句并执行

这里写目录标题 一. 需求分析二. 从日志中抽取出指定字段,并切分为若干个子文件三. 生成查询执行计划四. 生成查询的SQL语句五. 检查并执行 一. 需求分析 有如下日志文件,假设日志文件中有10000条数据,要求将全部的TRANSACTIONID抽取出来&am…

在VSCode中创建Java项目

在VSCode中创建Java项目 首先,保证安装了Java的JDK. WinR -> 输入cmd -> 输入 java -version -> 然后可以看到安装的JDK版本,如果没安装可以去找教程。 JDK安装参考教程 打开VSCode,打开扩展(Ctrl Shift S&#xff…

鸿蒙(HarmonyOS)项目方舟框架(ArkUI)之AlphabetIndexer组件

鸿蒙(HarmonyOS)项目方舟框架(ArkUI)之AlphabetIndexer组件 一、操作环境 操作系统: Windows 10 专业版、IDE:DevEco Studio 3.1、SDK:HarmonyOS 3.1 二、AlphabetIndexer组件 可以与容器组件联动用于按逻辑结构快速定位容器显…

每日五道java面试题之java基础篇(四)

第一题. 访问修饰符 public、private、protected、以及不写(默认)时的区别? Java 中,可以使⽤访问控制符来保护对类、变量、⽅法和构造⽅法的访问。Java ⽀持 4 种不同的访问权限。 default (即默认,什么也不写&…

Elasticsearch:混合搜索是 GenAI 应用的未来

在这个竞争激烈的人工智能时代,自动化和数据为王。 从庞大的存储库中有效地自动化搜索和检索信息的过程的能力变得至关重要。 随着技术的进步,信息检索方法也在不断进步,从而导致了各种搜索机制的发展。 随着生成式人工智能模型成为吸引力的中…

【Python如何求出所有3位数的回文数】

回文数就是正向读和逆向读都相同的数,如66,626,72127 1、求出所有3位数的回文数python代码如下: # 输出所有3位数的回文数 for i in range(100, 1000): # 从100循环到999,不包含1000if str(i) str(i)[::-1]: # 如…

CSS3 基本语法

CSS3 基本语法 1. CSS3 新增长度单位 rem 根元素字体大小的倍数,只与根元素字体大小有关。vw 视口宽度的百分之多少 10vw 就是视口宽度的 10% 。vh 视口高度的百分之多少 10vh 就是视口高度的 10% 。vmax 视口宽高中大的那个的百分之多少。(了解即可&am…

centos中docker操作+安装配置django并使用simpleui美化管理后台

一、安装docker 确保系统是CentOS 7并且内核版本高于3.10,可以通过uname -r命令查看内核版本。 更新系统软件包到最新版本,可以使用命令yum update -y。 安装必要的软件包,包括yum-utils、device-mapper-persistent-data和lvm2。使用命令yum install -y yum-utils devic…

【制作100个unity游戏之23】实现类似七日杀、森林一样的生存游戏10(附项目源码)

本节最终效果演示 文章目录 本节最终效果演示系列目录前言快捷栏绘制UI代码控制快捷列表信息 源码完结 系列目录 前言 欢迎来到【制作100个Unity游戏】系列!本系列将引导您一步步学习如何使用Unity开发各种类型的游戏。在这第23篇中,我们将探索如何制作…

C语言-----自定义类型-----结构体枚举联合

结构体和数组一样,都是一群数据的集合,不同的是数组当中的数据是相同的类型,但是结构体中的数据类型可以不相同,结构体里的成员叫做成员变量 结构体类型是C语言里面的一种自定义类型,我们前面已经了解到过int,char,fl…

2024 年 5 款适用于免费 iPhone 数据恢复的工具软件

搜索一下,你会发现许多付费或免费的iPhone数据恢复工具声称它们可以帮助你以很高的成功率找回所有丢失的数据。然而,这正是问题所在。真的很难做出选择。为了进一步帮助您解决数据丢失问题,我们在此列出了 5 款最好的免费 iPhone 恢复软件供您…

计算机网络——07协议层次及服务模型

协议层次及服务模型 协议层次 网络是一个复杂的系统 网络功能复杂:数字信号的物理信号承载、点到点、路由、rdt、进程区分、应用等现实来看,网络的许多构成元素和设备: 主机路由器各种媒体的链路应用协议硬件,软件 问题是&am…

C++ 贪心 区间问题 区间分组

给定 N 个闭区间 [ai,bi] ,请你将这些区间分成若干组,使得每组内部的区间两两之间(包括端点)没有交集,并使得组数尽可能小。 输出最小组数。 输入格式 第一行包含整数 N ,表示区间数。 接下来 N 行&…