【标准IO】fseek函数、ftell函数、fflush函数、getline函数

news2025/1/7 6:50:28

目录

  • fseek
  • ftell
  • rewind
  • fflush
  • getline

橙色

当你在文件中写入了10个字符后,又想把这10个字符读出来,该怎么做呢?因为有文件操作符指针的存在,此时该指针已经指在了这10个字符末尾,所以需要把该指针重定向,这就用了本文中所介绍的几个函数

fseek

在这里插入图片描述

fseek:设置流 stream 的文件位置为给定的偏移 offset,参数 offset 意味着从给定的 whence 位置查找的字节数。

int fseek(FILE *stream, long int offset, int whence)
  • stream — 这是指向 FILE 对象的指针,该 FILE 对象标识了流。
  • offset — 这是相对 whence 的偏移量,以字节为单位。
  • whence — 这是表示开始添加偏移 offset 的位置。它一般指定为下列常量之一:
    在这里插入图片描述
  • 如果成功,则该函数返回零,否则返回非零值。

ftell

ftell:返回给定流 stream 的当前文件位置。

long int ftell(FILE *stream)
  • stream — 这是指向 FILE 对象的指针,该 FILE 对象标识了流。
  • 该函数返回位置标识符的当前值。如果发生错误,则返回 -1L,全局变量 errno 被设置为一个正值。

程序实例——求程序的有效字节

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char **argv){

    FILE *fp;
    if(argc < 2) {
        fprintf(stderr, "Usage...\n");
        exit(1);
    }

    fp = fopen(argv[1], "r");
    if(fp == NULL) {
        perror("fopen()");
        exit(1);
    }
	// 将指针定位在文件末尾
    fseek(fp, 0, SEEK_END);

    printf("%d\n", ftell(fp));

    exit(0);
}

在这里插入图片描述

rewind

rewind:设置文件位置为给定流 stream 的文件的开头。

void rewind(FILE *stream)

相当于(void) fseek(stream, 0, SEEK_SET);

注意:
fseekftell中偏移offset的修饰类型是long,因此只能对2G左右大小的文件进行操作,否则会超出long的范围;

fseekoftello则将偏移的修饰类型使用typedef定义为offset_t,具体类型交由系统决定,因此不存在文件大小的限制。但是这两个函数不是C标准库函数,而是隶属于POSIX标准(POSIX是标准C库的超集,或者说,C库是普通话,而POSIX是方言)。

fflush

fflush:刷新流 stream 的输出缓冲区。刷新,指的是将缓冲区(内存上的一片区域)的内容写入到磁盘(外存)中,或者输出到终端上显示。

int fflush(FILE *stream)
  • 如果参数为NULL(即没传递参数),则刷新所有的已打开的流
  • 如果成功,该函数返回零值。如果发生错误,则返回 EOF,且设置错误标识符(即 feof)。

代码示例

#include <stdio.h>

int main() {
    printf("Before while(1)");
    while(1);
    printf("After while(1)");
    exit(0);
}

打印结果:

// 什么都不打印

原因:
对于标准输出,输出缓冲区刷新的时机:

  • 输出缓冲区满
  • 或者遇到换行符\n
  • 强制刷新,或者进程结束

因此,可以修改为:

#include <stdio.h>
#include <stdlib.h>
int main() {
    // 遇到\n刷新
    printf("Before while(1)\n");
    while(1);
    printf("After while(1)\n");
    exit(0);
}

或者修改为:

#include <stdio.h>
#include <stdlib.h>

int main() {

    printf("Before while(1)");
    // 强制刷新
    fflush(stdout);
	// 或者 fflush(NULL);
    
    while(1);

    printf("After while(1)");

    exit(0);
}

缓冲区的作用:大多数情况下是好事,合并系统调用,增加程序的吞吐量。

缓冲的分类:

  • 行缓冲line buffered:针对标准输出(终端设备),有换行刷新,缓冲满刷新,强制刷新三种,后两个和全缓冲一致;
  • 全缓冲fully buffered:默认缓冲机制(除标准输出【终端设备】,例如重定向到文件),有缓冲满刷新,强制刷新两种,强制刷新例如调用fflush函数,或者进程结束时也会强制刷新;此时换行符仅仅只是个换行符,没有刷新功能;
  • 无缓冲unbuffered:例如stderr,需要立即输出,数据会立即读入内存或者输出到外存文件和设备上;

setvbuf:定义流 stream 应如何缓冲。理解即可。

int setvbuf(FILE *stream, char *buffer, int mode, size_t size)
  • stream — 这是指向 FILE 对象的指针,该 FILE 对象标识了一个打开的流。
  • buffer — 这是分配给用户的缓冲。如果设置为 NULL,该函数会自动分配一个指定大小的缓冲。
  • mode — 这指定了文件缓冲的模式:
    在这里插入图片描述

getline

之前介绍的函数,都不能获得完整的一整行(有缓冲区大小的限制),而下面介绍的getline函数则可以动态分配内存,当装不下完整一行时,又会申请额外的内存来存储。

getline是C++标准库函数,但不是C标准库函数,而是POSIX所定义的标准库函数(在POSIX IEEE Std 1003.1-2008标准出来之前,则只是GNU扩展库里的函数)。在gcc编译器中,对标准库stdio进行了扩展,加入了一个getline函数。

getline会生成一个包含一串从输入流读入的字符的字符串,直到以下情况发生会导致生成的此字符串结束:

  • 到文件结束
  • 遇到函数的定界符
  • 输入达到最大限度

函数原型:

#include <stdio.h>
ssize_t getline(char **lineptr, size_t *n, FILE *stream);
  • lineptr:指向存放该行字符的指针,如果是NULL,则有系统帮助malloc,请在使用完成后free释放。该参数是一个二级指针,因此传参需要一级指针的地址。即函数会把读取到的字符串的首地址存放在一级指针中。
// 传参:
char *ptr;
// 函数内的实际操作:
// 假设读取到的字符串Hello的首地址为0x000
&ptr = 0x000; // 此时ptr就指向了Hello
  • n:如果是由系统malloc的指针填0;

  • stream:函数需要读取的FILE流

  • 返回值:成功返回读取的字节数,失败或读完返回-1。

代码示例:

int main(int argc, char **argv) {
    FILE *fp;
    // 一定要初始化,否则指针会指向内存中的随机位置
    char *linebuf = NULL;
    size_t linesize = 0;
    if(argc < 2) {
        fprintf(stderr, "Usage...\n");
    }
    fp = fopen(argv[1], "r");
    if(fp == NULL) {
        perror("fopen()");
        exit(1);
    }
    while(1) {
        // 当返回-1时则读完
    	if(getline(&linebuf, &linesize, fp) < 0)
            break;
       	printf("%d\n", strlen(linebuf));
    }
    fclose(fp);
    exit(0);
}

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

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

相关文章

RT-Thread Studio学习(十七)虚拟串口

RT-Thread Studio学习&#xff08;十七&#xff09;虚拟串口 一、简介二、新建RT-Thread项目并使用外部时钟三、启用USB设备功能四、测试 一、简介 本文将基于STM32F407VET芯片介绍如何在RT-Thread Studio开发环境下实现USB虚拟串口。 硬件及开发环境如下&#xff1a; OS WI…

油管公式(全)

原文&#xff1a;The Youtube Formula 译者&#xff1a;飞龙 协议&#xff1a;CC BY-NC-SA 4.0 前言 每个人都应该有一个 YouTube 频道。真的每个人&#xff0c;尤其是品牌。当我看到没有在 YouTube 上存在的品牌时&#xff0c;我觉得他们疯了。任何人都不利用这个机会是难以想…

python-基础篇-变量

文章目录 变量的基本使用目标01. 变量定义1) 变量演练1 —— iPython2) 变量演练 2 —— PyCharm3) 变量演练 3 —— 超市买苹果思考题 02. 变量的类型2.1 变量类型的演练 —— 个人信息2.2 变量的类型2.3 不同类型变量之间的计算1) **数字型变量** 之间可以直接计算2) **字符串…

从零开始:直播电商APP开发全流程解析

本篇文章&#xff0c;小编将从零开始&#xff0c;全面解析直播电商APP的开发流程&#xff0c;涵盖了关键的技术要点和开发阶段的关键步骤。 第一阶段&#xff1a;需求分析与规划 此阶段的关键任务包括&#xff1a; 1.用户需求调研 2.功能规划 3.技术选型 第二阶段&#xf…

安卓平板局域网内远程控制工控机方法

安卓平板局域网内远程控制工控机方法 将所需要远程控制的工控机通过网线连接到具有WiFi功能的路由器上&#xff0c;将安卓平板连接上WiFi&#xff0c;如下图所示 下载NoMachine远程软件安装包&#xff0c;官网地址&#xff1a;https://www.nomachine.com/ 点击Download now按钮…

图论:最短路(dijkstra算法、bellman算法、spfa算法、floyd算法)详细版

终于是学完了&#xff0c;这个最短路我学了好几天&#xff0c;当然也学了别的算法啦&#xff0c;也是非常的累啊。 话不多说下面看看最短路问题吧。 最短路问题是有向图&#xff0c;要求的是图中一个点到起点的距离&#xff0c;其中我们要输入点和点之间的距离&#xff0c;来求…

【Docker】安装Nginx容器并部署前后端分离项目

&#x1f389;&#x1f389;欢迎来到我的CSDN主页&#xff01;&#x1f389;&#x1f389; &#x1f3c5;我是Java方文山&#xff0c;一个在CSDN分享笔记的博主。&#x1f4da;&#x1f4da; &#x1f31f;推荐给大家我的专栏《Docker实战》。&#x1f3af;&#x1f3af; &…

代码随想录算法训练营第十一天|● 20. 有效的括号 ● 1047. 删除字符串中的所有相邻重复项 ● 150. 逆波兰表达式求值

文章目录 20.有效的括号思路&#xff1a;代码&#xff1a; 1047. 删除字符串中的所有相邻重复项思路代码1:栈储存代码2&#xff1a;双指针 150. 逆波兰表达式求值思路&#xff1a;题外话代码 20.有效的括号 思路&#xff1a; 由于栈结构的特殊性&#xff0c;非常适合做对称匹配…

单体架构、微服务和无服务器架构

前言 在这篇文章中&#xff0c;我将演示在决定使用单体架构、微服务架构和无服务器架构时的权衡的简化心智模型。目标是突显每种风格的固有优势和缺陷&#xff0c;并提供关于何时选择哪种架构风格的指导。 单体架构 对于小团队或项目来说是理想的入门架构。它简单易上手&…

Python sleep函数用法:线程睡眠

如果需要让当前正在执行的线程暂停一段时间&#xff0c;并进入阻塞状态&#xff0c;则可以通过调用 time 模块的 sleep(secs) 函数来实现。该函数可指定一个 secs 参数&#xff0c;用于指定线程阻塞多少秒。 当前线程调用 sleep() 函数进入阻塞状态后&#xff0c;在其睡眠时间…

131. 分割回文串 - 力扣(LeetCode)

问题描述 给你一个字符串 s&#xff0c;请你将 s 分割成一些子串&#xff0c;使每个子串都是 回文串 。返回 s 所有可能的分割方案。 回文串 是正着读和反着读都一样的字符串。 输入示例 s "aab"输出示例 [["a","a","b"],["…

面试2024.1.20

简单介绍下你做的项目。 这个神领物流项目是一个前后端分离的项目&#xff0c;前段他有3个客户端&#xff08;用户端为微信小程序、司机端和快递员端为app&#xff09;一个管理端&#xff08;pc&#xff09;&#xff0c;后端用的技术栈用的是SpringAlibabaCloud、数据库用的是M…

《Aspect-Sentiment-Multiple-Opinion Triplet Extraction》论文阅读

文章目录 文章介绍文章模型encoder部分ATE任务TOWE任务ATSA任务 番外 文章地址&#xff1a; https://arxiv.org/abs/2110.07303v1 文章介绍 目前的关于ASTE三元组提取的方面级情感分析论文大多关注于简单的句式&#xff0c;比如一个方面实体仅有一个意见词加以修饰&#xff0c…

CCC数字钥匙设计【NFC基础】--LPCD相关介绍

关于NFC卡检测&#xff0c;主要可以分成两个步骤&#xff1a; 1、LPCD低功耗检测&#xff0c;唤醒NFC读卡器。 2、唤醒后&#xff0c;NFC读卡器或MCU控制器轮询Type A、Type B、Type F、Type V&#xff08;ISO15693&#xff09;等卡类型。 本文主要介绍LPCD相关功能&#xff…

AI向所有的绝症宣战?2024年将被AI颠覆的行业-医疗健康

近年来&#xff0c;人工智能技术在我国得到了迅猛发展&#xff0c;不仅在互联网、金融、交通、零售、农业等领域取得了显著成果&#xff0c;还逐渐渗透到了医疗健康行业。预测2024年&#xff0c;人工智能将在医疗领域的应用发挥更深远的影响&#xff0c;甚至有可能颠覆整个医疗…

【MySQL】where和having的区别

&#x1f34e;个人博客&#xff1a;个人主页 &#x1f3c6;个人专栏&#xff1a;数据库 ⛳️ 功不唐捐&#xff0c;玉汝于成 目录 前言 正文 用途: 使用位置: 操作对象: 聚合函数: 示例&#xff1a; 结语 我的其他博客 前言 数据库中的 WHERE 和 HAVING 子句在 SQL 查…

【Linux】python版本控制

文章目录 1.查看目前python的版本2.添加软件源并更新3.选择你想要下载的版本4.警示&#xff1a;没必要设置默认版本误区千万千万不要覆盖python3软链接解决办法 5.安装pip换源 6.环境管理 网上有很多教程都是教导小白去官方下载之后编译安装。但是&#xff0c;小白连cmake是什么…

【LeetCode: 295. 数据流的中位数 + 堆】

&#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…

羊驼系列大模型LLaMa、Alpaca、Vicuna

羊驼系列大模型&#xff1a;大模型的安卓系统 GPT系列&#xff1a;类比ios系统&#xff0c;不开源 LLaMa让大模型平民化 LLaMa优势 用到的数据&#xff1a;大部分英语、西班牙语&#xff0c;少中文 模型下载地址 https://huggingface.co/meta-llama Alpaca模型 Alpaca是斯…

Datawhale 强化学习笔记(三)基于策略梯度(policy-based)的算法

文章目录 参考基于价值函数的缺点策略梯度算法REINFORCE 算法策略梯度推导进阶策略函数的设计离散动作的策略函数连续动作的策略函数 参考 第九章 策略梯度 之前介绍的 DQN 算法属于基于价值(value-based)的算法&#xff0c;基于策略梯度的算法直接对策略本身进行优化。 将策…