C++进阶篇 day7

5.3

关于标准IO的缓冲区问题

缓冲区的分类

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

案例:

点击查看代码
#include <iostream>
#include <stdio.h>
using namespace std;

int main(){
	printf("行缓存的大小为:%d\n",stdout->_IO_buf_end-stdout->_IO_buf_base);
	printf("行缓存的大小为:%d\n",stdout->_IO_buf_end-stdout->_IO_buf_base);

	printf("行缓存的大小为:%d\n",stdin->_IO_buf_end-stdin->_IO_buf_base);

	int num=0;

	cin>>num;
	printf("行缓存的大小为:%d\n",stdin->_IO_buf_end-stdin->_IO_buf_base);

	FILE *fp=NULL;
	if((fp=fopen("./aa.txt","r"))==NULL){
		perror("fopen error");
		return -1;
	}

	printf("全缓存的大小为:%d\n",fp->_IO_buf_end-fp->_IO_buf_base);

	fgetc(fp);

	printf("全缓存的大小为:%d\n",fp->_IO_buf_end-fp->_IO_buf_base);

	fclose(fp);

	printf("不缓存的大小为:%d\n",stderr->_IO_buf_end-stderr->_IO_buf_base);

	perror("error");

	printf("不缓存得大小:%d\n",stderr->_IO_buf_end-stderr->_IO_buf_base);

	return 0;
}

缓冲区的刷新时机

缓冲区刷新时机:fflush

使用:

点击查看代码
#include <stdio.h>
int fflush(FILE *stream);
//功能:刷新给定的文件指针对应的缓冲区
//参数:文件指针
//返回值:成功返回0,失败返回EOF并置位错误码

行缓存的刷新时机

点击查看代码
#include<iostream>
#include<stdio.h>
using namespace std;
int main(int argc, const char *argv[])
{
/*1、验证缓冲区如果没有达到刷新时机,就不会将数据进行刷新
printf("hello world"); //在终端上打印输出一个hello world,没有到缓冲区的
刷新时机,就不会输出数据
while(1); //阻塞程序不让进程结束
*/
/*2、当程序结束后,会刷新行缓冲区
printf("hello world");
*/
/*3、当遇到换行时,会刷新行缓存
printf("hello world\n");
while(1);
*/
/*4、当输入输出发生切换时,也会刷新行缓存
int num = 0;
printf("请输入>>>"); //向标准输出缓冲区中写入一组数据,没有换行符号
scanf("%d", &num); //cin >> num
*/
/*5、当关闭行缓存对应的文件指针时,也会刷新行缓存
printf("hello world"); //向标准输出缓冲区中写入数据,没有换行
fclose(stdout); //关闭标准输出指针
while(1);
*/
/*6、使用fflush函数手动刷新缓冲区时,行缓存会被刷新
printf("hello world");
fflush(stdout);
while(1);
*/
//7、当缓冲区满了后,会刷新行缓存,行缓存大小:1024字节
for(int i=0; i<1025; i++)
{
printf("A");
}
while(1); //防止程序结束
全缓存的刷新时机
return 0;
}

全缓存的刷新时机

点击查看代码
#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", fp); //将字符串写入到文件中
while(1);
*/
/*2、当遇到换行时,也不会刷新全缓存
fputs("hello world\n", fp); //将字符串写入到文件中
while(1);
*/
/*3、当程序结束后,会刷新全缓存
fputs("hello world 你好 星球!\n", fp);
*/
/*4、当输入输出发生切换时,会刷新全缓存
fputs("I love China\n", fp); //向文件中输出一个字符串
fgetc(fp); //从文件中读取一个字符,主要是让输入输出发生切换
while(1);
*/
/*5、当关闭缓冲区对应的文件指针时,也会刷新全缓存
fputs("上海欢迎你", fp);
fclose(fp); //刷新文件指针
while(1);
*/
/*6、当手动刷新缓冲区对应的文件指针时,也会刷新全缓存
fputs("上海欢迎你", fp);
fflush(fp); //刷新文件指针
while(1);
*/
//7、当缓冲区满了后,再向缓冲区中存放数据时会刷新全缓存
for(int i=0; i<4097; i++)
{
fputc('A', fp); //循环将单字符放入文件中
对于不缓存的刷新时机,只要放入数据,立马进行刷新
2.9 格式化读写:fprintf/fscanf
}
while(1);
return 0;
}

不缓存

对于不缓存的刷新时机,只要放入数据,立马进行刷新

格式化读写:fprintf/fscanf

fprintf

功能:向指定的文件中输出一个格式串
int fprintf(FILE *stream, const char *format, ...);
参数1:文件指针
参数2:格式串,可以包含可是控制符,%d(整数),%s(字符串),%f(小数),%lf(小数)
参数3:可变参数,输出项列表,参数个数参数2中的格式控制符的个数决定
返回值EOF

fscanf

int fscanf(FILE *stream, const char *format, ...);
功能:从指定的文件中以指定的格式读取数据,放入程序中
参数1:文件指针
参数2:格式串,可以包含格式控制符,%d(整数)、%s(字符串)、%f(小数)、%lf(小数)
参数3:可变参数,输入项地址列表,参数个数由参数2中的格式控制符的个数决定
返回值:成功返回读入的项数,失败返回EOF并置位错误码

点击查看代码
#include <iostream>
#include <stdio.h>
using  namespace std;

int main(){
	fprintf(stdout,"%d %lf %s\n",520,3.14,"I Love xingqiu");

	int num=0;
	fscanf(stdin,"%d",&num);
	printf("num = %d\n",num);


	//1.控制台输入输出
	FILE *fp=NULL;
	if((fp=fopen("./usr.txt","w"))==NULL){
		perror("fopen error");
		return -1;
	}

	fprintf(fp,"%s %d","admin",123456);

	fclose(fp);


	//2.在usr.txt写入addmin 123456
	if((fp = fopen("./usr.txt","r"))==NULL){
		perror("fopen error");
		return -1;
	}
	char usrName[20]="";
	int pwd=0;
	fscanf(fp,"%s %d",usrName,&pwd);

	fclose(fp);

	//3.读入usrName pwd
	printf("usrName = %s, pwd = %d\n",usrName,pwd);

	//输出
	return 0;
}
posted @ 2025-05-04 08:12  北燃  阅读(28)  评论(0)    收藏  举报