文章目录
- 缓冲区的分类
- 缓冲区的刷新时机
缓冲区的分类
- 行缓存:和终端文件相关的缓冲区叫做行缓存,行缓冲区的大小为1024字节,对应的文件指
针:stdin
、stdout
- 全缓存:和外界文件相关的缓冲区叫做全缓存,全缓冲区的大小为4096字节,对应的文件指
针:fp
- 不缓存:和标准出错相关的缓冲区叫不缓存,不缓存的大小为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); //0int num = 0;//两种输入都可以//scanf("%d", &num);//Ccin >> num;//C++printf("行缓存的大小为:%d\n", stdin->_IO_buf_end - stdin->_IO_buf_base); //1024//2.验证全缓存的大小为4096FILE *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); //0return 0;
}
验证结果:
缓冲区的刷新时机
对于三种缓冲区,都可以使用缓冲区刷新函数fflush
来手动刷新。
#include <stdio.h> /*
功能:刷新给定的文件指针对应的缓冲区
参数:文件指针
返回值:成功返回0,失败返回EOF并置位错误码
*/
int fflush(FILE *stream);
除了手动刷新,遇到以下情况缓冲区也会自动刷新:
- 行缓存
- 当程序结束后
- 当遇到换行时
- 当输入输出发生切换时
- 当关闭行缓存对应的文件指针时
- 当缓冲区满了后(行缓存大小: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;
}
- 全缓存
- 当程序结束后
- 当输入输出发生切换时
- 当关闭缓冲区对应的文件指针时
- 当缓冲区满了后(全缓存大小: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;
}