缓冲区及流状态、cin.sync()、cin.clear()、cin.ignore()

1、输出缓冲区

每一个IO对象都管理一个缓冲区,输入时先把内容输入到缓冲区中,当缓冲区被刷新时将内容写入到真是的输出设备或者文件,缓冲区被刷新有以下几种情况:

1、程序正常结束,作为main函数返回的一部分,将清空所有的缓冲区

2、在一些不确定的情况下缓冲区可能已经满了,因此在写下一个值之前会对缓存区进行刷新

3、用操纵符显示的进行刷新:

endl:刷新流,输出内容换行

flush:刷新流,但不在输出中添加任何形式的字符

ends:在缓冲区中插入空字符null并刷新

4、在每次输出操作执行完后,用unitbuf操作符设置流的内部状态,从而清空缓冲区

5、将输入流与输出流关联。

2、流状态的控制

以下代码用于输出failbit、eofbit、badbit、goodbit几个标志的常量值

cout<<"ios::failbit:"<<ios::failbit<<endl;
cout<<"ios::eofbit:"<<ios::eofbit<<endl;
cout<<"ios::badbit:"<<ios::badbit<<endl;
cout<<"ios::goodbit"<<ios::goodbit<<endl;

以下代码用于输出failbit、eofbit、badbit、goodbit几个标志当前的状态,1表示可用,0表示错误状态

cout<<"cin.fail():"<<cin.fail()<<endl;
cout<<"cin.eof():"<<cin.eof()<<endl;
cout<<"cin.bad():"<<cin.bad()<<endl;
cout<<"cin.good:"<<cin.good()<<endl;

3、cin.clear()、cin.sync()、cin.ignore()用法

cin.clear()是将错误状态更改为有效状态
cin.sync()是清除缓冲区中的未读信息
cin.ignore()是忽略缓冲区中指定个数的字符

int v;
char c,d;
while(cin>>v,!cin.eof()){
  if(cin.fail()){
   cerr<<"bad data!"<<endl;
   cout<<"cin.fail():"<<cin.fail()<<endl;
   cin.ignore();       
    c=getchar();
   cout<<"c:"<<c<<endl;
   cin.clear();
   d=getchar();
   cout<<"d:"<<d<<endl;
   cout<<"cin.fail():"<<cin.fail()<<endl;
   }
}

当输入1 2 3 a 4 5 e时,上述程序cin.ignore()在cin.clear()之前执行,在c=getchar(); cout<<"c:"<<c<<endl;仍然输出a;表明此时cin.ignore()并没有执行,否则在用getchar()获取缓冲区的字符串时不会输出a。此时while循环中cin>>获得的仍然是a,因此程序陷入死循环。

int v;
char c,d;
while(cin>>v,!cin.eof()){
  if(cin.fail()){
   cerr<<"bad data!"<<endl;
   cout<<"cin.fail():"<<cin.fail()<<endl;
    c=getchar();
   cout<<"c:"<<c<<endl;
   cin.clear();
  cin.ignore();
   d=getchar();
   cout<<"d:"<<d<<endl;
   cout<<"cin.fail():"<<cin.fail()<<endl;
     }
}

上述程序cin.ignore()在cin.clear()之后执行,执行完cin.ignore后,缓冲区中的字符被舍弃,程序继续到while循环执行。

要特别注意cin.ignore()一定要在cin.clear()之后执行;如果cin为错误标志是不能执行cin.ignore()函数中忽略字符的操作的,必须先用cin.clear()重新将错误标志置为可用,才能执行ignore()中忽略字符的操作,不懂得可以看ignore源码。

4、

void main(){
	int data;
	while(cin>>data,!cin.eof()){
		if(cin.bad())
			throw runtime_error("IO stream corrupted");
		if(cin.fail()){
			cerr<<"bad data,try again!"<<endl;
			cin.clear(istream::failbit);
			continue;
		}
	}
}

c++ primer上有一个错误程序,对以上程序的改进方法如下

第一种方法(cin.sync();cin.clear())

#include<iostream>
using namespace std;
void main(){
	int data;
	while(cin>>data,!cin.eof()){
		if(cin.bad())
			throw runtime_error("IO stream corrupted");
		if(cin.fail()){
			cerr<<"bad data,try again!"<<endl;
			cin.sync();  
			cin.clear();
			continue;
		}
	}
}

第二种方法(cin.clear();cin.sync())

#include<iostream>
using namespace std;
void main(){
	int data;
	while(cin>>data,!cin.eof()){
		if(cin.bad())
			throw runtime_error("IO stream corrupted");
		if(cin.fail()){
			cerr<<"bad data,try again!"<<endl;
			cin.clear();
			cin.sync();
			continue;
		}
	}
}

第三种方法(cin.clear();cin.ignore());以下用cin.ignore()的地方均可换为cin.sync()

#include<iostream>
using namespace std;
void main(){
	int data;
	while(cin>>data,!cin.eof()){
		if(cin.bad())
			throw runtime_error("IO stream corrupted");
		if(cin.fail()){
			cerr<<"bad data,try again!"<<endl;
			cin.clear();
			cin.ignore();
			continue;
		}
	}
}

第四种方法(cin.clear(istream::goodbit);cin.ignore)

#include<iostream>
using namespace std;
void main(){
	int data;
	while(cin>>data,!cin.eof()){
		if(cin.bad())
			throw runtime_error("IO stream corrupted");
		if(cin.fail()){
			cerr<<"bad data,try again!"<<endl;
			cin.clear(istream::goodbit);
			cin.ignore();
			continue;
		}
	}
}

第五种方法(cin.clear(istream::failbit ^ cin.rdstate());cin.ignore())

#include<iostream>
using namespace std;
void main(){
	int data;
	while(cin>>data,!cin.eof()){
		if(cin.bad())
			throw runtime_error("IO stream corrupted");
		if(cin.fail()){
			cerr<<"bad data,try again!"<<endl;
			cin.clear(istream::failbit ^ cin.rdstate());
			cin.ignore();
			continue;
		}
	}
}
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值