zoukankan      html  css  js  c++  java
  • fflush()函数总结

    1. 概述

    • **函数名: ** fflush()
    • **功 能: ** 清除读写缓冲区,需要立即把输出缓冲区的数据进行物理写入时
    • 头文件: stdio.h
    • 原型: int fflush(FILE *stream),其中stream是要冲洗的流

    2. 函数说明

    • fflush()会强迫将缓冲区内的数据写回参数stream 指定的文件中. 如果参数stream 为NULL,fflush()会将所有打开的文件数据更新.

    3. fflush(stdout) 例子

    // 例1 fflus(stdout)
    #include<stdio.h>
    #include<unistd.h>
    int main()
    {
    	printf("hello");
    	// fflush(stdout);
    	fork();
    	return 0;
    }
    

    4. 返回值

    • fflush 的返回值类型是int类型,那么这个int类型具体的返回是什么呢?
      如果成功刷新,fflush返回0。指定的流没有缓冲区或者只读打开时也返回0值。返回EOF指出一个错误。

    • 注意:如果fflush返回EOF,数据可能由于写错误已经丢失。当设置一个重要错误处理器时,最安全的是用setvbuf函数关闭缓冲或者使用低级I/0例程,如open、close和write来代替流I/O函数。

    5. fflush(stdin) & fflush(stdout)一些问题

    • 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),并且这个更新流最近执行的操作不是输入,那么flush函数将把任何未被写入的数据写入stream指向的文件(如标准输出文件stdout)。否则,flush函数的行为是不确定的。fflush(NULL)清空所有输出流和上面提到的更新流。如果发生写错误,flush函数会给那些流打上错误标记,并且返回EOF,否则返回0。
      由此可知,如果 stream 指向输入流(如 stdin),那么 fflush 函数的行为是不确定的

    • 下面来看下fflush(stdin)的一些解释和用法
      fflush(stdin)比较容易理解,即清理标准输入流,把多余的仍未被保存的数据丢掉。

    比如,下面这个小程序:

    int a;
    char str[10];
    
    cin>>a;
    cout<<a<<endl;
    cin>>str;
    cout<<str<<endl;
    

    目地很简单:从stdin获得一个整数存入a,接着立马打印出来;从stdin获得一个字符串存入str,也立马打印出来。但是下面这种可能需要特别考虑:在首行输入了两个整数,在cin>>a之后,stdin缓冲还有一个整数没被读取。接下来,不等输入字符串,就直接把上面多出来的数字存入到str中去并打印。

    某种程度上这是操作不规范造成的,但是程序应该要有健壮性,程序员应该提前预防这种不规范的操作。可以在程序界面上提示“请输入1个整数”,甚至有时候不厌其烦的强调和警告也必要。当然,本例为求简单,并不在UI友好方面做文章。这时,可以在cin>>str语句前插入fflush(stdin),如此一来就可以清空标准输入缓冲里多余的数据。

    fflush(stdout)跟fflush(stdin)类似,是对标准输出流的清理,但是它并不是把数据丢掉,而是及时地打印数据到屏幕上。为了更好的理解它,需要知道一个事实:标准输出是以『行』为单位进行的,也即碰到 才打印数据到屏幕。这就可能造成延时,如下面这几行代码:

    int a;
    
    printf_s("input one number:");
    fflush(stdout);\#1
    scanf_s("%d",&a);
    

    如果没有#1那行代码,在某些平台上就可能迟迟看不到"input one number"被打印到屏幕上来,因为它没有回车。这时候,fflush(stdout)就起到及时输出的作用。
    但是在Windows平台上,似乎并看不出差别来。也即MSFT已经将stdout的输出改成及时生效了。
    fflush函数被广泛使用在多线程、网络编程的消息处理中。

    6.printf()竟然是一个行缓冲函数 T T

    • printf是一个行缓冲函数
      printf函数是标准函数,最终会调用到系统调用函数,printf函数会掉用到write系统函数;但是调用write函数需要满足一些条件件。
      (1)缓冲区满
      (2)遇到
      (3)调用fflush函数来冲洗缓冲区
      (4)scanf读取缓冲区的内容
      (5)调用printf函数的进程或线程结束会调用fflush函数
      检测缓冲区的大小为1024B。

    好记性不如烂笔头呀,还是太菜T T
    本文参考自以下文章:

    1. http://blog.csdn.net/yeyuangen/article/details/6743416
    2. http://baike.baidu.com/link?url=zKir2V4iKgQjQDWe9dDbqbJuLEn2Nx7Jr4e2fqD92CVkBBrzM7hbo9tZYVCY-gPuhRr7L7_gHEOlchRePi1c-FPzfTjOWarVeRELUAp5TTi
    3. http://bbs.chinaunix.net/thread-693309-1-1.html
    4. http://baike.baidu.com/item/fflush?fr=aladdin#3
    5. http://blog.chinaunix.net/uid-30058258-id-5029847.html
  • 相关阅读:
    Spring MVC程序中得到静态资源文件css,js,图片文件的路径问题总结
    【转】MySQL数据丢失讨论
    【摘】 pt-query-digest工具一解
    【摘】Mysql备份还原数据库之mysqldump实例及参数详细说明
    【原】redis插件安装
    【摘】linux中fstab解说
    【原】mysql慢日志分析
    【原】带宽、流量单位换算关系
    【转】Linux查看内存大小和插槽
    【转】bind
  • 原文地址:https://www.cnblogs.com/WArobot/p/6731155.html
Copyright © 2011-2022 走看看