fflush(stdio)、fflush(stdout)详解

解释:

fflush(stdio):清空输入缓冲区

fflush(stdout):清空输出缓冲区

我们输入输出的内容都会先放到输入输出缓冲区中,那么先认识一下缓冲区。

1、什么是缓冲区?

       缓冲区就是我们常说的缓存,属于内存的一部分。它依据对应的输入设备和输出设备把内存的一部分空间分为输入缓冲区和输出缓冲区。

2、为什么会有缓冲区?

       一句话:减少对磁盘的读写次数,提高计算机的运行效率。

      why?  磁盘是机械结构,读取磁盘上面的东西需要磁头转动到相应的位置进行读取,而内存是电,一瞬间到达。减少磁盘的读取也利于磁盘的使用长久。

3、缓冲区类型?

     全缓冲、行缓冲、不带缓冲

     3.1全缓冲 :填满I/O缓存后进行实际的I/O操作,eg:磁盘的读写

     3.2行缓冲 :输入输出遇到换行符时执行真正的I/O操作,eg:键盘的输入

     3.3不带缓冲 :直接进行显示,相当于直接刷新数据,,eg:stderr错误信息快速输出到标准错误文件中

一、fflush(stdin)使用过程和分析过程如下:

测试环境VS2019

TestCode1:

#include <stdio.h>
int main()
{
    int a;
    char b;
    scanf_s("%d", &a);
    scanf_s("%c", &b);
    printf("a=%d\n", a);
    printf("b=%d\n", b);
    return 0;
}

Out1:

分析:只输入a,然后输出a,b,为什么没有输入b,但是b有值??

因为在输入a后按回车,此时相当于把回车键加入了缓冲区,scanf此时把回车键接受了,b的值就是回车键,回车键的ASCII值:10。

这就是常说的scanf会吃回车键!!!

如下例子吃空格是不是更明显一点

TestCode2

那么这样就会导致我们得不到我们自己需要输入的b值,此时就用到了fflush(stdin)。

测试环境VS2013(fflush在vs2019上面存在问题)

TestCode3:

#include <stdio.h>
int main()
{
    int a;
    char b;
    scanf_s("%d", &a);
    fflush(stdin);
    scanf_s("%c", &b);
    printf("a=%d\n", a);
    printf("b=%d\n", b);
    return 0;
}

分析:这次当输入1的时候,不会直接输出a,b的值,因为输入1后,我们利用fflush把缓冲区清空,相当于把回车键在缓冲区里面清空,此时需要输入东西,就走到了第二个scanf_s需要继续输入东西,我们输入2,此时就输出了2的ASCII值:50.

二、fflush(stdout)使用过程和分析过程如下:

作用:调用printf()时,输出的结果一般会被标准库缓存起来,可能不会及时打印写出到输出设备上面,此时就可以用fflush(stdout)强制把缓存内容进行输出。

eg环境(VS2013):

TestCode4:

分析:

不加fflush(stdout)和加上fflush(stdout)打印一样,但是其实本质上面他们显示过程不一样。

不加fflush(stdout):调用了printf后,把1,2,3,4,5值都放到了输出缓冲区里,最后一次性进行了显示。

加了fflush(stdout):调用了printf后,把1,2,3,4,5值每次放一个就输出一个,相当于着5个值从输出缓冲区一个一个蹦出来的。只是人眼看起来打印一样。

这样看起来不明显,其实当出现多进程的时候,这种情况就有可能发生,比如调用fork()的时候,子进程没有退出,父进程不能及时输出需要的内容。

eg:(linux环境)

#include<stdio.h>
#include<unistd.h>

int main()
{

    //TODO
    int a = 10;
    printf("a = %d", a);
    fflush(stdout);
    fork();
    //TODO
    return 0;
}

此时就可以为了让父进程需要输出a的时候及时输出a。

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值