关于fflush(stdin)清空输入缓存流~VC6与gcc的区别~

如何在 Linux 中清空缓冲区和缓存内存? 在 Linux 系统中,缓冲区和缓存内存起着重要的作用,用于提高系统性能和优化磁盘访问。然而,有时候我们可能需要清空缓冲区和缓存内存,以释放系统资源或解决某些性能问题。本文将详细介绍如何在 Linux 中清空缓冲区和缓存内存,并提供一些实际的示例。 阅读详情
1. 为什么 fflush(stdin) 是错的?
首先请看以下程序:

#include <stdio.h>
int main( void )
{
int i;

for (;;)
   {
      fputs("Please input an integer: ", stdout);
      scanf("%d", &i);
      printf("%d\n", i);
}

   return 0;
}

这个程序首先会提示用户输入一个整数,然后等待用户输入,如果用户输入的是整数,
程序会输出刚才输入的整数,并且再次提示用户输入一个整数,然后等待用户 输入。
但是一旦用户输入的不是整数(如小数或者字母),假设 scanf 函数最后一次得到的整数是 2 ,
那么程序会不停地输出“Please input an integer: 2”。
这是因为 scanf("%d", &i); 只能接受整数,如果用户输入了字母,则这个字母会遗留在“输入缓冲区”中。
因为缓冲中有数据,故而 scanf 函数不会等待用户输入,直接就去缓冲中读取,可是缓冲中的却是字母,
这个字母再次被遗留在缓冲中,如此反复,从而导致不停地输出“Please input an integer: 2”。

也许有人会说:“居然这样,那么在 scanf 函数后面加上‘fflush(stdin);’,把输入缓冲清空掉不就行了?”
然而这是错的!
C和C++的标准里从来没有定义过 fflush(stdin)。
也许有人会说:“可是我用 fflush(stdin) 解决了这个问题,你怎么能说是错的呢?”
的确,某些编译器(如VC6)支持用 fflush(stdin) 来清空输入缓冲,
但是并非所有编译器都要支持这个功能(linux 下的 gcc 就不支持),
因为标准中根本没有定义 fflush(stdin)。
MSDN 文档里 也清楚地写着
fflush on input stream is an extension to the C standard(fflush 操作输入流是对 C 标准的扩充)。
当然,如果你毫不在乎程序的移植性,用 fflush(stdin) 也没什么大问题。
以下是 C99 对 fflush 函数的定义:

int fflush(FILE *stream);
如果 stream 指向输出流或者更新流(update stream),
并且这个更新流最近执行的操作不是输入,
那么 fflush 函数将把这个流中任何待写数据传送至宿主环境(host environment)写入文件。
否则,它的行为是未定义的。

原文如下:

int fflush(FILE *stream);
If stream points to an output stream or an update stream in which
the most recent operation was not input, the fflush function causes
any unwritten data for that stream to be delivered to the host environment
to be written to the file; otherwise, the behavior is undefined.

其中,宿主环境可以理解为操作系统或内核等。

由此可知,如果 stream 指向输入流(如 stdin),那么 fflush 函数的行为是不确定的。故而使用 fflush(stdin)   是不正确的,至少是移植性不好的。

2.    清空输入缓冲区的方法
虽然不可以用 fflush(stdin),但是我们可以自己写代码来清空输入缓冲区。只需要在 scanf 函数后面加上几句简单的代码就可以了。

       /* C 版本 */
       #include <stdio.h>


       int main( void )
       {
         int i, c;
             for ( ; ; )
         {
            fputs("Please input an integer: ", stdout);
            scanf("%d", &i);

         if ( feof(stdin) || ferror(stdin) )
            { /* 如果用户输入文件结束标志(或文件已被读完), */
               /* 或者发生读写错误,则退出循环             */
         
                   /* do something */
                   break;
            }
            /* 没有发生错误,清空输入流。                 */
            /* 通过 while 循环把输入流中的余留数据“吃”掉 */
            while ( (c = getchar()) != '\n' && c != EOF ) ;    /*可直接将这句代码当成fflush(stdio)的替代,直接运行可清除输入缓存流*/
            /* 使用 scanf("%*[^\n]"); 也可以清空输入流, */
            /* 不过会残留 \n 字符。                          */

            printf("%d\n", i);
         }

         return 0;
       }


       /* C++ 版本 */
       #include <iostream>
       #include <limits> // 为了使用numeric_limits


    using std::cout;
       using std::endl;
       using std::cin;
       using std::numeric_limits;
       using std::streamsize;


    int main()
       {
         int value;
         for ( ; ; )
         {
            cout << "Enter an integer: ";
            cin >> value;
            if ( cin.eof() || cin.bad() )
            { // 如果用户输入文件结束标志(或文件已被读完),
               // 或者发生读写错误,则退出循环

                // do something
                   break;
            }
            // 读到非法字符后,输入流将处于出错状态,
            // 为了继续获取输入,首先要调用 clear 函数
            // 来清除输入流的错误标记,然后才能调用
            // ignore 函数来清除输入流中的数据。
            cin.clear();
            // numeric_limits<streamsize>::max() 返回输入缓冲的大小。
            // ignore 函数在此将把输入流中的数据清空。
            // 这两个函数的具体用法请读者自行查询。
            cin.ignore( numeric_limits<streamsize>::max(), '\n' );

            cout << value << '\n';
         }

      return 0;
       }

参考资料:

ISO/IEC 9899:1999 (E) Programming languages— C 7.19.5.2 The fflush function

The C Programming Language 2nd Edition By Kernighan & Ritchie

ISO/IEC 14882(1998-9-01)Programming languages — C++
保姆级教程:用MATLAB搞定双目相机标定,从导入图片到参数解读全流程 本文提供了一份详细的MATLAB双目相机标定全流程指南,涵盖从图片准备到参数解读的每个环节。重点讲解了棋盘格选择、拍摄技巧、MATLAB工具箱设置及参数优化,帮助读者避免常见错误并提升标定精度。特别适合机器人导航、三维重建等领域的开发者。 阅读详情

相关推荐

VOS3000线路对接、路由配置与路由分析操作教程

通过本教程,你应该已经掌握了VOS3000的线路对接、路由配置和路由分析的基本操作。添加备用路由:为常用前缀添加备用路由,确保在主路由失效时呼叫仍能正常进行。进入线路管理:点击“系统管理” -> “线路管理” -> “添加线路”。查看日志:在“系统日志”中查看路由选择情况,确保路由配置正确。失败原因:查看失败呼叫的原因(如“无应答”、“线路忙”等)。线路选择:选择之前添加的线路(如“供应商A”)。保存并启用:填写完毕后,点击“保存”并启用路由。路由名称:自定义一个名称(如“路由A”)。

AI_wx_3307623172的博客 2970

清除缓冲区的几种方法

一、缓冲区的作用 一般缓冲区的作用是为了防止频繁的读写。 A:往缓冲区里写,这里会有一个写的等待时间,并不总是有数据需要写; B: 从缓冲区里读,这里就有一个读间(没有数据或数据不全)的等待时间; 使用缓冲区可以减小程序输入时的等待,程序线程可以腾出CPU时间做其它的工作; 二、缓冲区的问题 缓冲区在提升了程序效率的同时,也带来了一些问题。 在项目的编写的工程中,很...

konghouy的博客 3万+

【GAN实战】基于pytorch-CycleGAN与pix2pix的自定义数据集训练全攻略

本文详细解析了基于PyTorch的CycleGAN与pix2pix模型在自定义数据集上的完整训练流程。核心在于根据数据是否成对来正确选择模型:pix2pix适用于严格配对的“孪生”数据,而CycleGAN则擅长处理非配对的“散装”数据集。文章从数据准备、配置训练到测试应用,提供了全链路实战指南与关键参数调优心得,帮助开发者高效实现图像到图像的风格转换。

x2y3z4a5b的博客 704

输入时必要清空缓冲区的情况及其含空格字符串读取等输入需求实现

清空缓冲区的目的和常见的清空方法,实现全部清空或选择性部分清除缓冲区,同时介绍利用缓冲区机制实现理想读取并记录多个字符串

螺蛳粉只吃炸蛋的走风的博客 2711

AD24-层次原理图的设计

4)在原理图关联对话框中双击需要放置方块图的子图,即激活方块图的放置,单击母图的空白处进行放置。3)设计-Create Sheet From Sheet,进入原理图关联对话框。4)放置-添加图纸入口,放置方块图的内部I/O端口并进行名称更改。2)放置-页面符,放置页面符,并执行Table完成属性设置。5)执行Ctrl+W,端口和内部I/O端口对应连接。1)创建一个工程并完成子图的每页原理图的设计。1)新建项目,创建Main原理图页。3)放置-的端口,放置方块图的端口。以上,就是层次原理图页的设计。

qq_52761962的博客 4914

RPA 财务共享中心与RPA赋能

在和集团财务官交流的时候,客户经常会提到FSSC,其中有准备建立FSSC,正在建立FSSC,以及已建成FSSC正使用的,当中会有些对FSSC的疑虑和问题,所以花费些时间对FSSC进行了深入调研,从而也有幸拜读了王兴山、陈剑、梅震、钱自严等专业人士写的几本关于FSSC的书,对FSSC的前因后果有了更深入的认识,同时结合自己在FSSC的一些项目经验,故做了本次分享。 本文章主要分享财务共享中心以及R...

weixin_40244959的博客 2756

关于Java中Scanner缓冲区问题

死循环,错误

Coniary的博客 753

科研党必备:Zotero+Deepseek 打造AI文献阅读助手(附详细插件配置指南)

本文详细介绍了如何利用Zotero和Deepseek打造AI文献阅读助手,提升科研效率。从Zotero基础安装到中文文献处理插件茉莉花的配置,再到Deepseek API的集成与模型选择策略,全面覆盖了AI辅助阅读的关键环节。特别适合需要高效管理海量文献的科研工作者,显著提升文献筛选和分析速度。

backprop5master的博客 423

[Java基础] Scanner的缓冲区 以及 nextLine()输入的问题

Scanner的缓冲区 以及 next(),nextInt,nextLine()之间的区别 和 输入时的问题

花与树 2219

Calpuff模型实战:从气象数据预处理到污染物扩散模拟全流程指南

本文提供了一份详尽的Calpuff模型实战指南,涵盖从气象数据预处理、地形处理到污染物扩散模拟与结果可视化的全流程。重点解析了Calmet气象场构建、Calpuff核心参数配置,并与AERMOD模型进行对比,帮助环境工程师与科研人员掌握这一强大的三维非稳态拉格朗日扩散模型,以应对复杂地形、海岸熏烟等实际模拟挑战。

s4t5u6v7的博客 458

Python爬虫实战:全方位解析前程无忧(51job)职位详情爬取及反爬破解

平台规模:覆盖全国各行业、数百万条岗位信息。数据特点:职位描述详细,职位标签丰富。数据价值:支持招聘趋势分析、职业发展研究、薪资行情调研。推荐Python 3.10+,支持最新async特性与库兼容。

2201_76125261的博客 1486

清理缓冲区

读取数据,'\n'将数据放入缓冲区,数据被函数读取后还有'\n'留在缓冲区,所以getchar()函数是将遗留在缓冲区的'\n'读取了。注意:判断位置是EOF和'\n'的区别:EOF用于多组输入,逐次输入,每次输入都返回一个结果,用ctrl+z结束输入;'\n'用于清理缓冲区,是一次输入,逐个读取时的结束标志;修改代码:scanf函数遇到空格停止读取,留在缓冲区中的数据不止有'\n',需要getchar()多次读取。注意区分显示器上的'\n'和缓冲区中的'\n',缓冲区中的'\n'不在显示器上显示。

m0_74304693的博客 546

一点击打印电脑就卡死?资源管理器停止工作的解决方法

Windows11共享的HP1022n打印机导致客户端打印时资源管理器崩溃卡死,电脑停止工作。

gary18的专栏 578

c语言-利用getchar()清空缓冲区

本篇文章简要介绍了c语言中缓冲区的分类和利用getchar()清空缓冲区

pyc68的博客 2384

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

Scanner使用中缓冲区清空

在获取键盘输入时常常用到Scanner,但在连续使用Scanner的过程中会发生缓冲区不空,从而不会阻塞的问题。 System.out.print("请输入用户名:"); String userName=sc.nextLine(); System.out.print("请输入密码:"); String password=sc.nextLine(); 在上面的例子中就会出现在"请输入用

irisZhang 1万+

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

C语言中的缓冲区、清空缓冲区与ASCII码表详解

*ASCII(美国信息交换标准代码)**是一种用于表示字符的编码标准,使用7位二进制表示128个字符,包括英文字母、数字、标点符号和控制字符。ASCII码表在计算机系统中广泛使用,用于字符的存储和交换。缓冲区:用于临时存储输入输出数据,常用于提高程序性能。标准输入输出使用缓冲区进行数据的处理和显示。清空缓冲区:通过可以清空输出缓冲区,而清空输入缓冲区可以通过使用getchar()或scanf格式控制符来实现。ASCII码表:ASCII码是计算机中常用的字符编码标准,通过它可以将字符和整数值互相转换。

m0_62599305的博客 1226

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

[C语言][总结] getchar()清除缓冲区

getchar()是最近看C语言教程看到的函数,大三的时候学C语言吊儿郎当,隐约听过老师说过这个函数,似乎与清除缓冲区有关,今天终于彻底了解了。 A.getchar()的使用 看一段代码,它实现的功能是输出我们输入的字母: 输入a,它输出a。这里getchar()的功能是获取键盘输入的字母,搭配putchar()来进行一个输出。 来看看while语句括号内的内容: ch=getchar(),这个ch在此前声明为int类型,而我们输入的a是字符,看起来出现了矛盾。其实原因是:getchar()的

matlabgreenman的博客 6412

C语言之清空缓存区

在C语言中,我们常常需要去清空缓存区,对于缓存区清空的重要性,接下来我们进行具体的说明。 首先我们先解释一下缓存区。1.缓存区C语言中的缓冲区又称为缓存,它是内存空间的一部分。   也就是说,在内存空间中预留了一定的存储空间,这些存储空间用来缓冲输入或输出的数据,这部分预留的空间就叫做缓冲区。     C语缓冲区分为三种类型:1、全缓冲 2、行缓冲 3、不带缓冲。   缓冲区根据其对应的是输

宇哲 9万+

c语言缓冲区类型,清空缓冲区,谈getchar、getch、getche

C语言缓冲区(缓存)详解 缓冲区(Buffer)又称为缓存(Cache),是内存空间的一部分。也就是说,在内存中 预留了一定的存储空间,用来暂时保存输入或输出的数据,这部分预留的空间就叫做缓冲 区。 缓冲区根据其对应的是输入设备还是输出设备,分为输入缓冲区和输出缓冲区。 为什么要引入缓冲区 比如从磁盘里取信息,我们先把读出的数据放在缓冲区,计算机再直接从缓冲区中取数 据,等缓冲区的数据取完后再去磁...

weixin_42528287的博客 3634

简单的清理缓冲区

在学习循环语句时,有几个例子:1.多组输入;2.清理缓冲区。希望能够将while循环与实际问题进行结合。缓冲区是内存空间的一部分。也就是说,在内存空间中预留了一定的存储空间,这些存储空间用来缓冲输入或输出的数据,这部分预留的空间就叫做缓冲区。缓冲区根据其对应的是输入设备还是输出设备,分为输入缓冲区和输出缓冲区。顾名思义,getchar()函数的功能是获取一个字符,而putchar()函数的功能是输出一个字符。下面,进行具体的getchar()函数的功能介绍:在下面的链接上有详细的介绍。

加油,考上985的研究生 1179

gcc下fflush(stdin)失效

今天编译一程序涉及到了键盘缓冲区的清除问题,在VC下完全没问题的代码却不能在gcc下运行成功,作此笔记以留念:  VC下代码:  #include  void main()  {          float a,b;          int tag=0;          char ch;          float result;          printf(

xinsuixiaofeiyu的专栏 2696

c语言清除文件缓存区,C语言之清空缓存区

在C语言中,我们常常需要去清空缓存区,对于缓存区清空的重要性,接下来我们进行具体的说明。首先我们先解释一下缓存区。1.缓存区C语言中的缓冲区又称为缓存,它是内存空间的一部分。也就是说,在内存空间中预留了一定的存储空间,这些存储空间用来缓冲输入或输出的数据,这部分预留的空间就叫做缓冲区。C语缓冲区分为三种类型:1、全缓冲 2、行缓冲 3、不带缓冲。缓冲区根据其对应的是输入设备还是输出设备,分为输入缓...

weixin_39652154的博客 5405

C语言清除缓冲区的函数

C语言中清除内存缓冲区的函数是fflush( ),清除输入缓冲区用fflush(stdin); 其中stdin表示标准输入。该函数通常用在输入类函数的前面,用以清除输入缓冲区中的内容,避免接收到上次残留的内容而出错。 但是ffplush不是标准库函数,在gcc下是不支持的,笔者通过许多网上的例子亲测,只有在VC6.0编译器下,fflush才能完成它的正常功能。 fflush()用于清空文件缓冲

哒哒的博客 1万+

清理vs临时文件,优化VS项目大小的代码

REM www.yjxsoft.com 清理项目垃圾文件 // del *.log *.ipch *.aps *.user /s del *.exe *.dll /s del *.sdf /s del *.ilk *.pdb *.exp *.tlog *.lastbuildstate /s del *.obj *.pch *.idb/s pause

sanqiuai的博客 640

C语言清除缓冲区方法

C语言清除缓冲区方法

jyx20171104的博客 509
上一篇: 设置linux启动时自动进入命令行界面
下一篇: libata error messages
Iphone4
博客等级 码龄17年 17粉丝 53原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值