fflush的概念和使用案例

ops/2025/2/4 17:47:42/
cle class="baidu_pl">
cle_content" class="article_content clearfix">
content_views" class="markdown_views prism-atom-one-light">cap="round" d="M5,0 0,2.5 5,5z" id="raphael-marker-block" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);">

<code>fflush()code> 是C语言标准库中用于控制输入/输出缓冲区的函数࿰c;其主要功能是强制刷新缓冲区࿰c;确保数据及时写入目标设备(如屏幕、文件)。以下是其概念和典型使用场景:


概念

  • 功能
    刷新指定流的缓冲区。对于输出流c;<code>fflush()code> 会将缓冲区中尚未写入的数据立即提交到目标设备(如文件或屏幕);对于输入流c;其行为是未定义的(可能丢弃缓冲区数据࿰c;但具体实现依赖系统)。
  • 头文件:<code>#include <stdio.h>code>
  • 函数原型
    <code class="prism language-c">class="token keyword">int class="token function">fflushclass="token punctuation">(FILE class="token operator">*streamclass="token punctuation">)class="token punctuation">;
    code>
    • 参数 <code>streamcode>:指向要刷新的流(如 <code>stdoutcode>、<code>stderrcode>、文件指针等)。
    • 返回值:成功返回 <code>0code>࿰c;失败返回 <code>EOFcode>。

核心使用场景

1. 强制输出到屏幕(避免延迟显示)

默认情况下࿰c;标准输出流(<code>stdoutcode>)是行缓冲的࿰c;即遇到换行符 <code>\ncode> 时才会刷新缓冲区。若未换行且需立即显示内容࿰c;需手动调用 <code>fflush(stdout)code>。

示例:实时显示进度条

<code class="prism language-c">class="token macro property">class="token directive-hash">#class="token directive keyword">include class="token string"><stdio.h>
class="token macro property">class="token directive-hash">#class="token directive keyword">include class="token string"><unistd.h>class="token keyword">int class="token function">mainclass="token punctuation">(class="token punctuation">) class="token punctuation">{class="token keyword">for class="token punctuation">(class="token keyword">int i class="token operator">= class="token number">0class="token punctuation">; i class="token operator"><= class="token number">100class="token punctuation">; iclass="token operator">++class="token punctuation">) class="token punctuation">{class="token function">printfclass="token punctuation">(class="token string">"\r进度: %d%%"class="token punctuation">, iclass="token punctuation">)class="token punctuation">; class="token comment">// \r回到行首࿰c;不换行class="token function">fflushclass="token punctuation">(class="token constant">stdoutclass="token punctuation">)class="token punctuation">;           class="token comment">// 强制立即输出class="token function">usleepclass="token punctuation">(class="token number">100000class="token punctuation">)class="token punctuation">;           class="token comment">// 模拟耗时操作class="token punctuation">}class="token function">printfclass="token punctuation">(class="token string">"\n"class="token punctuation">)class="token punctuation">;class="token keyword">return class="token number">0class="token punctuation">;
class="token punctuation">}
code>
2. 确保文件写入及时生效

文件流默认是全缓冲的࿰c;数据可能暂存于内存缓冲区中。调用 <code>fflush(fp)code> 可强制将缓冲区内容写入磁盘࿰c;防止程序崩溃或断电导致数据丢失。

示例:日志文件的实时写入

<code class="prism language-c">class="token macro property">class="token directive-hash">#class="token directive keyword">include class="token string"><stdio.h>class="token keyword">int class="token function">mainclass="token punctuation">(class="token punctuation">) class="token punctuation">{FILE class="token operator">*fp class="token operator">= class="token function">fopenclass="token punctuation">(class="token string">"log.txt"class="token punctuation">, class="token string">"a"class="token punctuation">)class="token punctuation">;class="token keyword">if class="token punctuation">(fp class="token operator">== class="token constant">NULLclass="token punctuation">) class="token punctuation">{class="token function">perrorclass="token punctuation">(class="token string">"文件打开失败"class="token punctuation">)class="token punctuation">;class="token keyword">return class="token number">1class="token punctuation">;class="token punctuation">}class="token keyword">for class="token punctuation">(class="token keyword">int i class="token operator">= class="token number">0class="token punctuation">; i class="token operator">< class="token number">5class="token punctuation">; iclass="token operator">++class="token punctuation">) class="token punctuation">{class="token function">fprintfclass="token punctuation">(fpclass="token punctuation">, class="token string">"日志条目 %d\n"class="token punctuation">, iclass="token punctuation">)class="token punctuation">;class="token function">fflushclass="token punctuation">(fpclass="token punctuation">)class="token punctuation">; class="token comment">// 每次写入后立即刷新࿰c;确保数据持久化class="token punctuation">}class="token function">fcloseclass="token punctuation">(fpclass="token punctuation">)class="token punctuation">;class="token keyword">return class="token number">0class="token punctuation">;
class="token punctuation">}
code>
3. 清空输入缓冲区(需谨慎)

虽然C标准未定义 <code>fflush(stdin)code> 的行为࿰c;但某些系统(如Linux)允许用它清空输入缓冲区中的残留数据。注意:此用法不具备可移植性

示例:清除多余的输入

<code class="prism language-c">class="token macro property">class="token directive-hash">#class="token directive keyword">include class="token string"><stdio.h>class="token keyword">int class="token function">mainclass="token punctuation">(class="token punctuation">) class="token punctuation">{class="token keyword">int numclass="token punctuation">;class="token keyword">char chclass="token punctuation">;class="token function">printfclass="token punctuation">(class="token string">"输入一个整数: "class="token punctuation">)class="token punctuation">;class="token function">scanfclass="token punctuation">(class="token string">"%d"class="token punctuation">, class="token operator">&numclass="token punctuation">)class="token punctuation">;class="token comment">// 清除输入缓冲区中的剩余字符class="token keyword">while class="token punctuation">(class="token punctuation">(ch class="token operator">= class="token function">getcharclass="token punctuation">(class="token punctuation">)class="token punctuation">) class="token operator">!= class="token char">'\n' class="token operator">&& ch class="token operator">!= class="token constant">EOFclass="token punctuation">)class="token punctuation">; class="token comment">// 方法1:手动循环读取class="token comment">// 或(仅限部分系统)class="token function">fflushclass="token punctuation">(class="token constant">stdinclass="token punctuation">)class="token punctuation">; class="token comment">// 方法2:可能不可靠class="token function">printfclass="token punctuation">(class="token string">"输入一个字符: "class="token punctuation">)class="token punctuation">;class="token function">scanfclass="token punctuation">(class="token string">"%c"class="token punctuation">, class="token operator">&chclass="token punctuation">)class="token punctuation">;class="token keyword">return class="token number">0class="token punctuation">;
class="token punctuation">}
code>

注意事项

  1. 输入流的未定义行为
    C标准未规定 <code>fflush(stdin)code> 的行为࿰c;应避免使用。如需清空输入缓冲区࿰c;推荐手动循环读取字符直到 <code>\ncode> 或 <code>EOFcode>。

  2. 性能影响
    频繁调用 <code>fflush()code> 会增加I/O操作次数࿰c;降低程序效率࿰c;需权衡实时性和性能。

  3. 多线程安全
    多线程环境中操作同一文件流时࿰c;需通过锁机制确保 <code>fflush()code> 的安全性。

  4. 错误处理
    检查返回值࿰c;若 <code>fflush()code> 失败(返回 <code>EOFcode>)࿰c;可能表示写入错误(如磁盘已满)。


总结

  • 主要用途
    • 强制输出内容到屏幕(如进度条、实时日志)。
    • 确保关键数据及时写入文件(如日志、数据库操作)。
  • 避免场景
    • 依赖 <code>fflush(stdin)code> 清空输入缓冲区(不可移植)。
    • 高频无意义刷新(降低性能)。

合理使用 <code>fflush()code> 可提升程序的稳定性和用户体验࿰c;但需结合具体场景谨慎操作。


http://www.ppmy.cn/ops/155626.html

相关文章

javaEE-8.JVM(八股文系列)

目录 一.简介 二.JVM中的内存划分 JVM的内存划分图: 堆区:​编辑 栈区:​编辑 程序计数器&#xff1a;​编辑 元数据区&#xff1a;​编辑 经典笔试题&#xff1a; 三,JVM的类加载机制 1.加载: 2.验证: 3.准备: 4.解析: 5.初始化: 双亲委派模型 概念: JVM的类加…

《手札·开源篇》从开源到商业化:中小企业的低成本数字化转型路径——一位甲方信息化负责人与开源开发者的八年双重视角

在中小企业数字化转型的浪潮中&#xff0c;"低成本"与"可持续性"始终是悬在决策者头顶的双刃剑。作为曾操盘过30信息化项目、主导过开源ERP二次开发的信息化老兵&#xff0c;我试图通过"甲方信息化负责人"与"开源开发者"的双重身份&am…

.Net WebAPI -[HttpPut(“{fileServiceId:int}“)]

[HttpPut("{fileServiceId:int}")] 这个写法是 ASP.NET Core 中的一个路由特性&#xff0c;用于定义一个 HTTP PUT 请求的路由&#xff0c;并指定路由参数的类型。 解析 HttpPut [HttpPut]&#xff1a; 这是一个 ASP.NET Core 的路由特性&#xff0c;用于标记一个方…

蓝桥杯python基础算法(2-1)——排序

目录 一、排序 二、例题 P3225——宝藏排序Ⅰ 三、各种排序比较 四、例题 P3226——宝藏排序Ⅱ 一、排序 &#xff08;一&#xff09;冒泡排序 基本思想&#xff1a;比较相邻的元素&#xff0c;如果顺序错误就把它们交换过来。 &#xff08;二&#xff09;选择排序 基本思想…

vue2和vue3指令

Vue 2 和 Vue 3 的指令系统非常相似&#xff0c;但 Vue 3 在指令方面进行了优化和扩展。以下是 Vue 2 和 Vue 3 中指令的对比&#xff1a; 1. 通用指令 这些指令在 Vue 2 和 Vue 3 中都可以使用&#xff0c;功能一致&#xff1a; 指令说明v-bind绑定 HTML 属性或组件 propsv-…

Joplin 插件在Vscode中无法显示图片

1.问题 在vscode里面装好joplin插件之后&#xff0c;无法显示图片内容。 粘贴的图片可以再vscode中显示&#xff0c;无法再joplin客户端显示 2.解决方法 这种情况是因为和vscode自带的MD编辑器的预览模式有冲突&#xff0c;或者没用通过专用方式上传图片。 方法一&#xff…

【LeetCode 刷题】二叉树(3)-二叉树的属性

此博客为《代码随想录》二叉树章节的学习笔记&#xff0c;主要内容为二叉树的属性相关的题目解析。 文章目录 101. 对称二叉树104.二叉树的最大深度111.二叉树的最小深度222.完全二叉树的节点个数110.平衡二叉树257. 二叉树的所有路径404.左叶子之和513.找树左下角的值112. 路…

CentOs9新手教程

CentOS 9是基于RHEL的CentOS Stream版本&#xff0c;主要用于开发和测试环境&#xff0c;不适合作为生产环境的稳定系统。它提供了最新的软件和功能&#xff0c;但可能存在不稳定性和兼容性问题。如果你需要一个稳定的生产环境&#xff0c;建议使用CentOS Linux版本。 安装环境…