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 以指示错误原因。

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

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

相关文章

【Vue】使用cmd命令创建vue项目

上一篇&#xff1a; node的安装与配置 https://blog.csdn.net/m0_67930426/article/details/134562278?spm1001.2014.3001.5502 目录 一.创建空文件夹专门存放vue项目 二. 查看node , npm 和vue脚手架的版本 三.安装vue脚手架 四.创建vue项目 五.运行项目 一.创建空文件…

Qt将打印信息输出到文件

将打印信息&#xff08;qDebug、qInfo、qWarning、qCritial等&#xff09;输出到指定文件来以实现简单的日志功能。 #include "mainwindow.h" #include <QApplication> #include <QLoggingCategory> #include <QMutex> #include <QDateTime>…

树_二叉搜索树的众树

//给你一个含重复值的二叉搜索树&#xff08;BST&#xff09;的根节点 root &#xff0c;找出并返回 BST 中的所有 众数&#xff08;即&#xff0c;出现频率最高的元素&#xff09;。 // // 如果树中有不止一个众数&#xff0c;可以按 任意顺序 返回。 // // 假定 BST 满足如…

面试题:公司规定所有接口都用 post 请求,这是为什么?

文章目录 前言get 与 post 的区别所有接口都用 post 请求&#xff1f;网友程墨 Morgan网友苏莉安网友大宽宽 前言 最近在逛知乎的时候发现一个有趣的问题&#xff1a;公司规定所有接口都用 post 请求&#xff0c;这是为什么&#xff1f; 看到这个问题的时候其实我也挺有感触的…

Java数据结构之《最短路径》(难度系数100)

一、前言&#xff1a; 这是怀化学院的&#xff1a;Java数据结构中的一道难度偏难(偏难理解)的一道编程题(此方法为博主自己研究&#xff0c;问题基本解决&#xff0c;若有bug欢迎下方评论提出意见&#xff0c;我会第一时间改进代码&#xff0c;谢谢&#xff01;) 后面其他编程题…

西工大计算机学院计算机系统基础实验一(环境配置)

首先&#xff0c;不要焦虑&#xff0c;稳住心态慢慢来&#xff0c;一点一点做&#xff0c;跟着作者把基础打好&#xff0c;比什么都重要。作者曾经经历过这份痛苦&#xff0c;知道它有多么不好受。当初的作者高中之前甚至都没有自己的一台笔记本&#xff0c;上了大学以后学C语言…

qt 5.15.2 主窗体事件及绘制功能

qt 5.15.2 主窗体事件及绘制功能 显示主窗体效果图如下所示&#xff1a; main.cpp #include "mainwindow.h"#include <QApplication>int main(int argc, char *argv[]) {QApplication a(argc, argv);MainWindow w;w.setFixedWidth(600);w.setFixedHeight(6…

java:slf4j、log4j、log4j2、logback日志框架的区别与示例

文章目录 背景SLF4J - 简单日志门面:Log4j - 强大而古老的日志框架:Log4j2 - Log4j的升级版:Logback - Log4j的继任者:比较Springboot集成slf4j、log4j2参考 背景 在Java开发中&#xff0c;日志记录是一个不可或缺的组成部分。为了满足不同的需求&#xff0c;Java社区涌现出多…

xilinx系列FPGA基于VIVADO的pin delay列表生成说明

目录 1 概述2 示例平台3 操作说明4 注意事项 xilinx系列FPGA基于VIVADO的pin delay列表生成说明 1 概述 本文用于讲诉xilinx系列FPGA基于VIVADO的pin delay列表生成说明&#xff0c;以及一些注意事项&#xff0c;为FPGA设计人员探明道路。 Pin delay 即FPGA内部die到pin的延时…

Unirest-Java:Java发起GET、POST、PUT、DELETE、文件上传,文件下载工具类介绍

一、简介 Unirest-Java是一个轻量级的HTTP客户端库&#xff0c;用于在Java应用程序中发送HTTP请求。 它提供了简单易用的API&#xff0c;可以方便地处理GET、POST、PUT、DELETE等HTTP方法。 Unirest-Java支持异步和同步请求&#xff0c;可以轻松地与JSON、XML等数据格式进行…

Linix服务器添加dns解析

Linix开通互联网域名地址出现&#xff0c;如下错误&#xff1a; 需要访问的服务器上添加dns解析 vim /etc/sysconfig/network-scripts/ifcfg-ens192 添加如下配置&#xff1a; DNS1202.96.134.13 重启网卡&#xff1a; systemctl restart network 注意如果是docker服务部署…

软著项目推荐 深度学习的水果识别 opencv python

文章目录 0 前言2 开发简介3 识别原理3.1 传统图像识别原理3.2 深度学习水果识别 4 数据集5 部分关键代码5.1 处理训练集的数据结构5.2 模型网络结构5.3 训练模型 6 识别效果7 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; 深度学习…

Vue实现条件渲染

&#x1f4d1;前言 本文主要是【Vue】——Vue实现条件渲染的文章&#xff0c;如果有什么需要改进的地方还请大佬指出⛺️ &#x1f3ac;作者简介&#xff1a;大家好&#xff0c;我是听风与他&#x1f947; ☁️博客首页&#xff1a;CSDN主页听风与他 &#x1f304;每日一句&am…

电商项目之Web实时消息推送(附源码)

文章目录 1 问题背景2 前言3 什么是消息推送4 短轮询5 长轮询5.1 demo代码 6 iframe流6.1 demo代码 7 SSE7.1 demo代码7.2 生产环境的应用 &#xff08;重要&#xff09; 8 MQTT 1 问题背景 扩宽自己的知识广度&#xff0c;研究一下web实时消息推送 2 前言 文章参考自Web 实时消…

数学建模-基于机器学习的家政行业整体素质提升因素分析

基于机器学习的家政行业整体素质提升因素分析 整体求解过程概述(摘要) 家政服务业即为家庭提供多种类服务的专门行业&#xff0c;在第三产业中占有重要地位。但近年来&#xff0c;由于人工智能家居产业的发展与客户对家政从业者的要求水平不断提高&#xff0c;家政行业仍面对较…

03、pytest初体验

官方实例 # content of test_sample.py def func(x):return x 1def test_ansewer():assert func(3) 5步骤解释 [100%]指的是所有测试用例的总体进度&#xff0c;完成后&#xff0c;pytest显示一个失败报告&#xff0c;因为func(3)没有返回5 注意&#xff1a;你可以使用ass…

Apache Doris 在某工商信息商业查询平台的湖仓一体建设实践

本文导读&#xff1a; 信息服务行业可以提供多样化、便捷、高效、安全的信息化服务&#xff0c;为个人及商业决策提供了重要支撑与参考。本文以某工商信息商业查询平台为例&#xff0c;介绍其从传统 Lambda 架构到基于 Doris Multi-Catalog 的湖仓一体架构演进历程。同时通过一…

c题目16:写一个递归函数,计算N阶乘

每日小语 一生中&#xff0c;最光辉的一天并非功成名就的那一天&#xff0c;而是从悲叹与绝望中产生对人生挑战与勇敢迈向意志的那一天。——福楼拜 自己思考 这个小语呢&#xff0c;我目前还达不到&#xff0c;只是顺其自然&#xff0c;很多东西做起来很有动力&#xff0c;…

OpenAI在中国,申请GPT-6、GPT-7商标

根据最新商标信息显示&#xff0c;OpenAI已经在中国提交了GPT-6和GPT-7的商标注册信息&#xff0c;分类是科学仪器和网站服务两大类。申请日期是今年的11月2日&#xff0c;目前处于审核状态。 该申请由知识产权代理公司完成&#xff0c;但申请人的地址正是OpenAI在美国公司的地…

Android Studio 模拟器设置独立窗口

目录 模拟器在窗口内部运行 设置成独立窗口 模拟器在窗口内部运行 操作起来十分不便 设置成独立窗口 Android Studio -> Preferences(Settings) -> Tools-> Emulator ->取消勾选 Launch in a tool window -> 点击右下角的 OK 按钮 -> 重启 Android Studio