【fflush】Linux环境下清空标准输入缓冲区 fflush(stdin) 无效

2024-04-14 06:18

本文主要是介绍【fflush】Linux环境下清空标准输入缓冲区 fflush(stdin) 无效,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

    • 一、误区
    • 二、问题描述
    • 三、解决方法
    • 四、原因

一、误区

不论从 字面意思 还是 某些技术文档 中,都可以看到 fflush(stdin) 是对标准输入缓冲区清空的标准方案;

然而,并不是!

深入了解一下 fflush(stdin) 之后,才发现这个锅得自己背,怪自己喜欢拿来就用,不去深入了解某些重要细节,给自己上了生动一课;

二、问题描述

环境:Ubuntu18.04

编译器:gcc version 7.3.0 (Ubuntu 7.3.0-27ubuntu1~18.04)

描述:在 scanf() 循环获取用户输入的时候,首次输入数据,总是会执行循环两次(第一次获取到垃圾数据,第二次获取到刚才输入的数据),此刻已经意识到是标准输入缓冲区的问题,然后疯狂加 fflush(stdin) 之后,并没有效果(尴尬.jpg);试图查看逻辑,查看数据类型,发现并没有问题;最后自己搜索了一通 fflush() 函数,找到了问题所在(让我高兴一会儿);

三、解决方法

Linux环境下,可以使用下面两种方案清空标准输入的缓冲区:

// 方案一
void empty_stdin() {int c;do {c = getchar();} while (c != '\n' && c != EOF);
}// 方案二
setbuf(stdin, NULL);

四、原因

fflush(stdin) 并非系统提供的标准定义,只是对系统函数的扩展而已,并没有得到编译器的统一支持;

所以,需要针对具体情况具体分析;

如下,摘自 Linux man手册 和 百度百科 对 fflush() 的描述:

# MAN文档中的部分描述
ubuntu@ubuntu:~/work/c/algo$ man 3 fflush# NAMEfflush - flush a stream# SYNOPSIS#include <stdio.h>int fflush(FILE *stream);# DESCRIPTIONFor  output streams, fflush() forces a write of all user-space buffered data for the given output or update stream via thestream's underlying write function.For input streams associated with seekable files (e.g., disk files, but not pipes or  terminals),  fflush()  discards  anybuffered data that has been fetched from the underlying file, but has not been consumed by the application.The open status of the stream is unaffected.If the stream argument is NULL, fflush() flushes all open output streams.For a nonlocking counterpart, see unlocked_stdio(3).# RETURN VALUEUpon successful completion 0 is returned.  Otherwise, EOF is returned and errno is set to indicate the error.
# 百度百科中对 fflush 使用的注意事项C 和 C++ 的标准里从来没有定义过 fflush(stdin)。也许有人会说:“可是我用 flush(stdin) 解决了这个问题,你怎么能说是错的呢?”的确,某些编译器(如VC6)支持用 fflush(stdin) 来清空输入缓冲,但是并非所有编译器都要支持这个功能(linux下的gcc就不支持,经我的GCC4.6.2测试),因为标准中根本没有定义fflush(stdin)。MSDN 文档里也清楚地写着:fflush on input stream is an extension to the C standard (fflush 操作输入流是对C标准的扩充)。
以下是 C99 对 fflush 函数的定义:int fflush(FILE *stream);如果stream指向输出流或者更新流(update stream),并且这个更新流最近执行的操作不是输入,那么fflush函数将把任何未被写入的数据写入stream指向的文件(如标准输出文件stdout)。否则,fflush函数的行为是不确定的。fflush(NULL)清空所有输出流和上面提到的更新流。如果发生写错误,flush函数会给那些流打上错误标记,并且返回EOF,否则返回0。由此可知,如果 stream 指向输入流(如 stdin),那么 fflush 函数的行为是不确定的。故而使用 fflush(stdin) 是不正确的。

—— 2018-11-27 ——

这篇关于【fflush】Linux环境下清空标准输入缓冲区 fflush(stdin) 无效的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/902288

相关文章

SpringBoot多环境配置数据读取方式

《SpringBoot多环境配置数据读取方式》SpringBoot通过环境隔离机制,支持properties/yaml/yml多格式配置,结合@Value、Environment和@Configura... 目录一、多环境配置的核心思路二、3种配置文件格式详解2.1 properties格式(传统格式)1.

Python标准库之数据压缩和存档的应用详解

《Python标准库之数据压缩和存档的应用详解》在数据处理与存储领域,压缩和存档是提升效率的关键技术,Python标准库提供了一套完整的工具链,下面小编就来和大家简单介绍一下吧... 目录一、核心模块架构与设计哲学二、关键模块深度解析1.tarfile:专业级归档工具2.zipfile:跨平台归档首选3.

Oracle数据库定时备份脚本方式(Linux)

《Oracle数据库定时备份脚本方式(Linux)》文章介绍Oracle数据库自动备份方案,包含主机备份传输与备机解压导入流程,强调需提前全量删除原库数据避免报错,并需配置无密传输、定时任务及验证脚本... 目录说明主机脚本备机上自动导库脚本整个自动备份oracle数据库的过程(建议全程用root用户)总结

Linux如何查看文件权限的命令

《Linux如何查看文件权限的命令》Linux中使用ls-R命令递归查看指定目录及子目录下所有文件和文件夹的权限信息,以列表形式展示权限位、所有者、组等详细内容... 目录linux China编程查看文件权限命令输出结果示例这里是查看tomcat文件夹总结Linux 查看文件权限命令ls -l 文件或文件夹

idea的终端(Terminal)cmd的命令换成linux的命令详解

《idea的终端(Terminal)cmd的命令换成linux的命令详解》本文介绍IDEA配置Git的步骤:安装Git、修改终端设置并重启IDEA,强调顺序,作为个人经验分享,希望提供参考并支持脚本之... 目录一编程、设置前二、前置条件三、android设置四、设置后总结一、php设置前二、前置条件

Linux系统中查询JDK安装目录的几种常用方法

《Linux系统中查询JDK安装目录的几种常用方法》:本文主要介绍Linux系统中查询JDK安装目录的几种常用方法,方法分别是通过update-alternatives、Java命令、环境变量及目... 目录方法 1:通过update-alternatives查询(推荐)方法 2:检查所有已安装的 JDK方

Linux系统之lvcreate命令使用解读

《Linux系统之lvcreate命令使用解读》lvcreate是LVM中创建逻辑卷的核心命令,支持线性、条带化、RAID、镜像、快照、瘦池和缓存池等多种类型,实现灵活存储资源管理,需注意空间分配、R... 目录lvcreate命令详解一、命令概述二、语法格式三、核心功能四、选项详解五、使用示例1. 创建逻

Linux下在线安装启动VNC教程

《Linux下在线安装启动VNC教程》本文指导在CentOS7上在线安装VNC,包含安装、配置密码、启动/停止、清理重启步骤及注意事项,强调需安装VNC桌面以避免黑屏,并解决端口冲突和目录权限问题... 目录描述安装VNC安装 VNC 桌面可能遇到的问题总结描js述linux中的VNC就类似于Window

linux下shell脚本启动jar包实现过程

《linux下shell脚本启动jar包实现过程》确保APP_NAME和LOG_FILE位于目录内,首次启动前需手动创建log文件夹,否则报错,此为个人经验,供参考,欢迎支持脚本之家... 目录linux下shell脚本启动jar包样例1样例2总结linux下shell脚本启动jar包样例1#!/bin

Go语言编译环境设置教程

《Go语言编译环境设置教程》Go语言支持高并发(goroutine)、自动垃圾回收,编译为跨平台二进制文件,云原生兼容且社区活跃,开发便捷,内置测试与vet工具辅助检测错误,依赖模块化管理,提升开发效... 目录Go语言优势下载 Go  配置编译环境配置 GOPROXYIDE 设置(VS Code)一些基本