P5 Linux 标准C库函数

目录

前言

01 标准输入、标准输出和标准错误

02 打开文件 fopen()

03 新建文件的权限

04 fclose()关闭文件

05 读文件和写文件

06 库函数 fseek 定位

6.1 lseek的使用

07 ftell()函数


前言

                                

🎬 个人主页:@ChenPi

🐻推荐专栏1: 《C++_@ChenPi的博客-CSDN博客》✨✨✨ 

🔥 推荐专栏2: 《Linux C应用编程(概念类)_@ChenPi的博客-CSDN博客》✨✨✨

🛸推荐专栏3: ​​​​​​《 链表_@ChenPi的博客-CSDN博客 》 ✨✨✨
🌺本篇简介  :  上一章我们学了系统调用,open,read,write,lseek等等,这章我们学习一下C库函数的open,read,write函数

在Linux环境下,个人平时还是使用系统调用多一些,但相对于说可移值性来说,还是C库函数好,

而且相关的API还会多些

01 标准输入、标准输出和标准错误

  1. 标准输入设备指的就是计 算机系统的标准的输入设备,通常指的是计算机所连接的键盘;
  2. 标准输出设备指的是计算机系统中用于 输出标准信息的设备,通常指的是计算机所连接的显示器
  3. 标准错误设备则指的是计算机系统中用于显示 错误信息的设备,通常也指的是显示器设备。

每个进程启动之后都会默认打开标准输入、标准输出以及标准错误,得到三个文件描述符

STDIN_FILENO    0 代表标准输入
STDOUT_FILENO   1 代表标准输出
STDERR_FILENO   2 代表标准错误

分别代表 0、1、2,这些宏定义在 unistd.h 头文件中:

/* Standard file descriptors. */ 
#define STDIN_FILENO 0 /* Standard input. */ 
#define STDOUT_FILENO1 /* Standard output. */ 
#define STDERR_FILENO 2 /* Standard error output. */ 


0、1、2 这三个是文件描述符,只能用于文件 I/O(read()、write()等),那么在标准 I/O 中,自然是无 法使用文件描述符来对文件进行 I/O 操作的,它们需要围绕 FILE 类型指针来进行,在 stdio.h 头文件中有相 应的定义,如下:

/* Standard streams. */ 
extern struct _IO_FILE *stdin; /* Standard input stream. */ 
extern struct _IO_FILE *stdout; /* Standard output stream. */ 
extern struct _IO_FILE *stderr; /* Standard error output stream. */ 
/* C89/C99 say they're macros. Make them happy. */ 
#define stdin stdin 
#define stdout stdout 
#define stderr stderr 

Tips:struct _IO_FILE 结构体就是 FILE 结构体,使用了 typedef 进行了重命名。

所以,在标准 I/O 中,可以使用 stdin、stdout、stderr 来表示标准输入、标准输出和标准错误。

02 打开文件 fopen()

在 0 所介绍的文件 I/O 中,使用 open()系统调用打开或创建文件

而在标准 I/O 中,我们将使用库函数fopen()打开或创建文件,fopen()函数原型如下所示:

#include <stdio.h> 
 
FILE *fopen(const char *path, const char *mode); 

函数参数和返回值含义如下:

  1. path:参数 path 指向文件路径,可以是绝对路径、也可以是相对路径。
  2. mode:参数 mode 指定了对该文件的读写权限,是一个字符串,稍后介绍。
  3. 返回值:调用成功返回一个指向 FILE 类型对象的指针(FILE *),该指针与打开或创建的文件相关联, 后续的标准 I/O 操作将围绕 FILE 指针进行。如果失败则返回 NULL,并设置 errno 以指示错误原因

参数 mode 字符串类型,可取值为如下值之一: 

mode参数取值

  • r 以只读方式打开文件。
  • r+ 以可读、可写方式打开文件。
  • w 以只写方式打开文件,如果参数 path 指定的文件 存在,将文件长度截断为 0;如果指定文件不存在 则创建该文件。
  • w+ 以可读、可写方式打开文件,如果参数 path 指定 的文件存在,将文件长度截断为 0;如果指定文件 不存在则创建该文件。
  • a 以只写方式打开文件,打开以进行追加内容(在 文件末尾写入),如果文件不存在则创建该文 件。
  • a +以可读、可写方式打开文件,以追加方式写入 (在文件末尾写入),如果文件不存在则创建该 文件。


03 新建文件的权限


由 fopen()函数原型可知,fopen()只有两个参数 path 和 mode,

不同于 open()系统调用,它并没有任何一 个参数来指定新建文件的权限。

当参数 mode 取值为"w"、"w+"、"a"、"a+"之一时,如果参数 path 指定的文 件不存在

则会创建该文件,

那么新的文件的权限是如何确定的呢?

虽然调用 fopen()函数新建文件时无法手动指定文件的权限,但却有一个默认值:

S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH (0666)
使用示例

  1. 使用只读方式打开文件: fopen(path, "r");
  2. 使用可读、可写方式打开文件: fopen(path, "r+");
  3. 使用只写方式打开文件,并将文件长度截断为 0,如果文件不存在则创建该文件:fopen(path, "w");


04 fclose()关闭文件

调用 fclose()库函数可以关闭一个由 fopen()打开的文件,其函数原型如下所示:

#include <stdio.h> 
 
int fclose(FILE *stream); 


参数 stream 为 FILE 类型指针,调用成功返回 0;失败将返回 EOF(也就是-1),并且会设置 errno 来 指示错误原因。

05 读文件和写文件

 fread()和 fwrite()库函数

对文件进行读、写操 作了,函数原型如下所示:

#include <stdio.h> 
 
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); 

库函数 fread()
用于读取文件数据,其参数和返回值含义如下:

  1. ptr:fread()将读取到的数据存放在参数 ptr 指向的缓冲区中;
  2. size:fread()从文件读取 nmemb 个数据项,每一个数据项的大小为 size 个字节,所以总共读取的数据大 小为 nmemb * size 个字节。
  3. nmemb:参数 nmemb 指定了读取数据项的个数。
  4. stream:FILE 指针。
  5. 返回值:调用成功时返回读取到的数据项的数目(数据项数目并不等于实际读取的字节数,除非参数size 等于 1);

库函数 fwrite()
用于将数据写入到文件中,其参数和返回值含义如下: 

  1. ptr:将参数 ptr 指向的缓冲区中的数据写入到文件中。
  2. size:参数 size 指定了每个数据项的字节大小,与 fread()函数的 size 参数意义相同。
  3. nmemb:参数 nmemb 指定了写入的数据项个数,与 fread()函数的 nmemb 参数意义相同。
  4. stream:FILE 指针。
  5. 返回值:调用成功时返回写入的数据项的数目(数据项数目并不等于实际写入的字节数,除非参数 size等于 1);如果发生错误,则 fwrite()返回的值将小于参数 nmemb(或者等于 0)。

由此可知,库函数 fread()、fwrite()中指定读取或写入数据大小的方式与系统调用 read()、write()不同, 前者通过 nmemb(数据项个数)*size(每个数据项的大小)的方式来指定数据大小,而后者则直接通过一 个 size 参数指定数据大小。 

06 库函数 fseek 定位

库函数 fseek()则用于标准 I/O,其函数原型如下所示:

#include <stdio.h> 
 
int fseek(FILE *stream, long offset, int whence); 

函数参数和返回值含义如下: stream:FILE 指针。

  1. offset:与 lseek()函数的 offset 参数意义相同。
  2. whence:与 lseek()函数的 whence 参数意义相同。
  3. 返回值:成功返回 0;发生错误将返回-1,并且会设置 errno 以指示错误原因;与 lseek()函数的返回值 意义不同,这里要注意!

调用库函数 fread()、fwrite()读写文件时,文件的读写位置偏移量会自动递增,使用 fseek()可手动设置 文件当前的读写位置偏移量。 

6.1 lseek的使用

  1. 譬如将文件的读写位置移动到文件开头处: fseek(file, 0, SEEK_SET);
  2. 将文件的读写位置移动到文件末尾: fseek(file, 0, SEEK_END);
  3. 将文件的读写位置移动到 100 个字节偏移量处: fseek(file, 100, SEEK_SET);
fread,fwrite,fseek综合小案例 
#include <stdio.h> 
#include <stdlib.h> 
 
 
int main(void) 
 
{ 
 FILE *fp = NULL; 
 char rd_buf[100] = {0}; 
 char wr_buf[] = "hello world"; 
 int ret; 
 
 /* 打开文件 */ 
 if (NULL == (fp = fopen("./test_file", "w+"))) { 
 perror("fopen error"); 
 exit(-1); 
 } 
 printf("文件打开成功!\n"); 
 
 /* 写文件 */ 
 if (sizeof(wr_buf) > 
 fwrite(wr_buf, 1, sizeof(wr_buf), fp)) { 
 
 printf("fwrite error\n"); 
 fclose(fp); 
 exit(-1); 
 } 
 printf("数据写入成功!\n"); 
 
 /* 将读写位置移动到文件头部 */ 
 if (0 > fseek(fp, 0, SEEK_SET)) { 
 perror("fseek error"); 
 fclose(fp); 
 exit(-1); 
 } 
 
 /* 读文件 */ 
 if (sizeof(wr_buf) > 
 (ret = fread(rd_buf, 1, sizeof(wr_buf), fp))) { 
 printf("fread error\n"); 
 fclose(fp); 
 exit(-1); 
 } 
 
 printf("成功读取%d 个字节数据: %s\n", ret, rd_buf); 
 
 /* 关闭文件 */ 
 fclose(fp); 
 exit(0); 
 
}

07 ftell()函数

库函数 ftell()可用于获取文件当前的读写位置偏移量,其函数原型如下所示:

#include <stdio.h> 
 
long ftell(FILE *stream); 


参数 stream 指向对应的文件,函数调用成功将返回当前读写位置偏移量;调用失败将返回-1,并会设置errno 以指示错误原因。

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

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

相关文章

2005-2021年地级市绿色发展注意力数据(根据政府报告文本词频统计)

2005-2021年地级市绿色发展注意力数据&#xff08;根据政府报告文本词频统计&#xff09; 1、时间&#xff1a;2005-2021年 2、指标&#xff1a;省、市、年份、一级指标、关键词、关键词词频、总词频 3、范围&#xff1a;270个地级市 4、来源&#xff1a;地级市政府工作报告…

最全Web前端校招面试真题合集(附答案)

历时半年&#xff0c;我们整理了这份市面上最全面的前端校招面试题解析大全。 包含了腾讯、字节跳动、百度、阿里、滴滴、美团、58、拼多多、360、新浪、搜狐等一线互联网公司面试被问到的题目。希望对大家参加前端校招有所帮助吧&#xff01; HTML 浏览器页面有哪三层构成&…

Android MVVM+coroutine+retrofit+flow+hilt

文章目录 Android MVVMcoroutineretrofitflowhilt概述依赖注入层数据层视图层模型视图层代码下载 Android MVVMcoroutineretrofitflowhilt 概述 代码结构&#xff1a; 依赖注入层 数据库&#xff1a; Module InstallIn(SingletonComponent::class) class DBModule {Singleto…

力扣第374场周赛题解

这一场周赛的题目是比较难的一次&#xff0c;写了1个多小时就写了两个题目。 首先第一题&#xff1a; 纯水题&#xff0c;遍历然后进行一下判断就可以解决了。这边就不放代码了。 第二题&#xff1a; 这个题目&#xff0c;我觉得难度非常大&#xff0c;其实代码量也不大都是很…

C语言--每日选择题--Day36

第一题 1. 以下关于指针的说法,正确的是() A&#xff1a;int *const p 与 int const *p等价 B&#xff1a;const int *p 与 int *const p等价 C&#xff1a;const int *p 与 int const *p 等价 D&#xff1a;int *p[10] 与 int (*p)[10] 等价 答案及解析 C const 在*的左侧&…

Hadoop学习笔记(HDP)-Part.02 核心组件原理

目录 Part.01 关于HDP Part.02 核心组件原理 Part.03 资源规划 Part.04 基础环境配置 Part.05 Yum源配置 Part.06 安装OracleJDK Part.07 安装MySQL Part.08 部署Ambari集群 Part.09 安装OpenLDAP Part.10 创建集群 Part.11 安装Kerberos Part.12 安装HDFS Part.13 安装Ranger …

Java操作Excel之 POI介绍和入门

POI是Apache 提供的一个开源的Java API&#xff0c;用于操作Microsoft文档格式&#xff0c;如Excel、Word和PowerPoint等。POI是Java中处理Microsoft文档最受欢迎的库。 截至2023/12&#xff0c; 最新版本时 POI 5.2.5。 JDK版本兼容 POI版本JDK版本4.0及之上版本> 1.83.…

【面试】Java最新面试题资深开发-JVM第一弹

问题一&#xff1a;Java中的垃圾回收机制 在Java中&#xff0c;垃圾回收是如何工作的&#xff0c;可以简要描述一下垃圾回收的算法有哪些吗&#xff1f; 在Java中&#xff0c;垃圾回收是一种自动管理内存的机制&#xff0c;它负责识别不再被程序引用的对象并释放其占用的内存…

有趣的代码——有故事背景的程序设计3

这篇文章再和大家分享一些有“背景”的程序设计&#xff0c;希望能够让大家学到知识的同时&#xff0c;对编程学习更感兴趣&#xff0c;更能在这条路上坚定地走下去。 目录 1.幻方问题 2.用函数打印九九乘法表 3.鸡兔同笼问题 4.字数统计 5.简单选择排序 1.幻方问题 幻方又…

力扣101. 对称二叉树(递归法,迭代法,层次遍历法)

题目&#xff1a; 给你一个二叉树的根节点 root &#xff0c; 检查它是否轴对称。 示例 1&#xff1a; 输入&#xff1a;root [1,2,2,3,4,4,3] 输出&#xff1a;true示例 2&#xff1a; 输入&#xff1a;root [1,2,2,null,3,null,3] 输出&#xff1a;false 代码及详细注释&…

⭐ Unity里 用Shader 去做实时动态绿幕抠图

1.先看一下效果 a.这是背景图片 b.抠完图之后(这里用的是扣去白色的) 2.shader代码如下 Shader "UniversalChromaKey" {Properties{_MainTex("Base (RGB)", 2D) "white" {}_Sens("Sensibilidad", Range(0,.9)) .3_Cutoff("R…

【AIGC】AI作图最全提示词prompt集合(收藏级)

目录 一、正向和负向提示词 二、作图参数 你好&#xff0c;我是giszz. AI做图真是太爽了&#xff0c;解放生产力&#xff0c;发展生产力。 但是&#xff0c;你是不是也总疑惑&#xff0c;为什么别人的图&#xff0c;表现力那么丰富呢&#xff0c;而且指哪打哪&#xff0c;要…

模拟电路学习笔记(一)之芯片篇(持续更新)

模拟电路学习笔记&#xff08;一&#xff09;之芯片篇&#xff08;持续更新&#xff09; 1.CD4047BE芯片 CD4047是一种包含高电压的多谐振荡器&#xff0c;该器件的操作可以在两种模式下完成&#xff0c;分别是单稳态和非稳态。CD4047需要一个外部电阻器和电容器来决定单稳态…

二叉树的前序中序后序遍历

二叉树的前序中序后序遍历-含递归和迭代代码 前序(中左右)中序(左中右)后序(左右中) 前序(中左右) 对于二叉树中的任意一个节点&#xff0c;先打印该节点&#xff0c;然后是它的左子树&#xff0c;最后右子树 A-B-D-E-C-F //递归 const preorderTraversal (root) > {const…

基于ROPNet项目训练modelnet40数据集进行3d点云的配置

项目地址&#xff1a; https://github.com/zhulf0804/ROPNet 在 MVP Registration Challenge (ICCV Workshop 2021)&#xff08;ICCV Workshop 2021&#xff09;中获得了第二名。项目可以在win10环境下运行。 论文地址&#xff1a; https://arxiv.org/abs/2107.02583 网络简介…

flask web学习之flask与http(一)

文章目录 一、请求响应循环二、HTTP请求1. 请求报文2. request对象3. 在flask中处理请求3.1 路由匹配3.2 设置监听的http方法3.3 URL处理 三、请求钩子 一、请求响应循环 每一个web应用都包含这种处理方式&#xff0c;请求-响应循环&#xff1a;客户端发出请求&#xff0c;服务…

实战经验分享,Python 连接 Oracle 踩坑实录

最近的一个测试任务需要测试 oracle 同步 hive 数据库的性能&#xff0c;那就需要对 oracle 数据库灌注测试数据。我就又打开了我的IDE&#xff0c;准备把我之前一下可以灌50w数据到 MySQL 的代码&#xff0c;改一改&#xff0c;直接用。 因为我在网上看到&#xff0c;语法上也…

基于Springboot的社区医院管理服务系统(有报告)。Javaee项目,springboot项目。

演示视频&#xff1a; 基于Springboot的社区医院管理服务系统&#xff08;有报告&#xff09;。Javaee项目&#xff0c;springboot项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系…

高低温交变湿热实验箱

产品概述 武汉凯迪正大高低温实验箱&#xff08;恒温恒湿试验箱&#xff09;乃针对各种材质表面处理&#xff0c;包含涂料、电镀、有机及无机皮膜&#xff0c;阳极处理&#xff0c;防锈油等防腐处理后测试其耐腐蚀性&#xff0c;从而确立产品的质量。 产品特点 1、内箱尺寸…

全网最新最全面的Appium自动化:Appium常用操作之按键类操作

按键类操作 按键类操作用来模拟在手机设备上进行按键操作&#xff08;推荐使用 方式一 &#xff09; 方式一、press_keycode(self,keycode,metastateNone,flagsNone)&#xff1a;模拟按键输入&#xff0c;其中&#xff1a; keycode&#xff1a;发送到设备的键值编码可以通过An…