C/C++标准IO的缓冲区

缓冲区的分类

  1. 行缓存:和终端文件相关的缓冲区叫做行缓存,行缓冲区的大小为1024字节,对应的文件指
    针:stdinstdout
  2. 全缓存:和外界文件相关的缓冲区叫做全缓存,全缓冲区的大小为4096字节,对应的文件指
    针:fp
  3. 不缓存:和标准出错相关的缓冲区叫不缓存,不缓存的大小为0字节,对应的文件指针:
    stderr

验证过程:

#include<stdio.h>
#include<iostream>

using namespace std;

int main(int argc, const char *argv[])
{
    //如果缓冲区没有被使用,则大小为0
    //只有被至少使用一次后,缓冲区的大小就确定了
    
    //1.可以通过两个方式求出行缓存的大小:1024
    //标准输出
    printf("行缓存的大小为:%d\n", stdout->_IO_buf_end - stdout->_IO_buf_base); //0
    //看似没使用,实际上打印文字也算使用
    printf("行缓存的大小为:%d\n", stdout->_IO_buf_end - stdout->_IO_buf_base); //1024
    
    //标准输入
    printf("行缓存的大小为:%d\n", stdin->_IO_buf_end - stdin->_IO_buf_base); //0
    int num = 0;
    //两种输入都可以
    //scanf("%d", &num);//C
    cin >> num;//C++
    printf("行缓存的大小为:%d\n", stdin->_IO_buf_end - stdin->_IO_buf_base); //1024
    
    
    //2.验证全缓存的大小为4096
    FILE *fp = NULL;
    if((fp = fopen("./ff.txt","r")) == NULL)
    {
        perror("fopen error");
        return -1;
    }
    //未使用时
    printf("全缓存的大小为:%d\n", fp->_IO_buf_end - fp->_IO_buf_base); //0
    //使用一次全缓存
    fgetc(fp);
    printf("全缓存的大小为:%d\n", fp->_IO_buf_end - fp->_IO_buf_base); //4096
    
    
    //3.验证不缓存的大小为0
    //未使用时
    printf("不缓存的大小为:%d\n", stderr->_IO_buf_end - stderr->_IO_buf_base); //0
    //使用一次不缓存
    perror("test error");
    printf("不缓存的大小为:%d\n", stderr->_IO_buf_end - stderr->_IO_buf_base); //0
    
    
    return 0;
}

验证结果:
在这里插入图片描述

缓冲区的刷新时机

对于三种缓冲区,都可以使用缓冲区刷新函数fflush来手动刷新。

#include <stdio.h> 

/*
功能:刷新给定的文件指针对应的缓冲区 
参数:文件指针 
返回值:成功返回0,失败返回EOF并置位错误码
*/
int fflush(FILE *stream); 

除了手动刷新,遇到以下情况缓冲区也会自动刷新:

  • 行缓存
    1. 当程序结束后
    2. 当遇到换行时
    3. 当输入输出发生切换时
    4. 当关闭行缓存对应的文件指针时
    5. 当缓冲区满了后(行缓存大小:1024字节)

示例:

#include<stdio.h>
#include<iostream>

using namespace std;

int main(int argc, const char *argv[])
{
   
    //1.当程序结束后
    printf("hello");
    return 0;
    
    //2.当遇到换行时
    printf("hello\n");
    while(1);//防止程序结束
    
    //3.当输入输出发生切换时
    int num = 0;
    printf("请输入:");
    scanf("%d", &num);
    
    //4.当关闭行缓存对应的文件指针(stdin stdout stderr)时
    printf("hello");
    fclose(stdout);    
    while(1);//防止程序结束
    
    //5.当缓冲区满了后(行缓存大小:1024字节)
    for(int i = 0; i < 1025; i++) 
    { 
    	printf("A"); 
    }
    while(1); //防止程序结束
    
    return 0;
}
  • 全缓存
    1. 当程序结束后
    2. 当输入输出发生切换时
    3. 当关闭缓冲区对应的文件指针时
    4. 当缓冲区满了后(全缓存大小:4096字节)

示例:

#include<iostream> 
#include<stdio.h> 

using namespace std; 
int main(int argc, const char *argv[])
{
	//打开一个文件 
	FILE *fp = NULL; 
	if((fp = fopen("./aa.txt", "r+")) == NULL) //以读写的形式打开文件 
	{ 
		perror("fopen error"); 
		return -1; 
	}
	
	//1.当程序结束后 
	fputs("hello world!\n", fp);
	return 0;

	//2.当输入输出发生切换时
	fputs("I love China\n", fp); //向文件中输出一个字符串 
	fgetc(fp); //从文件中读取一个字符,主要是让输入输出发生切换 
	while(1);

	//3.当关闭缓冲区对应的文件指针时
	fputs("北京欢迎你", fp); 
	fclose(fp); //刷新文件指针 
	while(1);

	//4.当缓冲区满了后(全缓存大小:4096字节)
	for(int i = 0; i < 4097; i++) 
    { 
    	fputc('A', fp); //循环将单字符放入文件中
    }
    while(1); //防止程序结束

	return 0;
}
  • 不缓存
    1.只要放入数据就会刷新缓冲区

示例:

#include<iostream> 
#include<stdio.h> 

using namespace std; 
int main(int argc, const char *argv[]) 
{ 
	//perror("a"); 
	//向标准出错中放入数据 
	fputs("A", stderr); //向标准出错缓冲区中写入一个字符A 
	while(1); //阻塞 
	return 0; 
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值