博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C++重载输入和输出操作符以及IO标准库中的刷新输入缓冲区残留字符问题
阅读量:4935 次
发布时间:2019-06-11

本文共 2573 字,大约阅读时间需要 8 分钟。

今天在做C++ Primer习题的14.11时,印象中应该挺简单的一题,结果却费了很长时间。

类定义:

 

typedef string Date;class CheckoutRecord{public:	CheckoutRecord(){book_id=-1;}	friend ostream& operator<<(ostream &os,const CheckoutRecord &obj);	friend istream& operator>>(istream &in,CheckoutRecord &obj);private:	double book_id;	string title;	Date date_borrowed;	Date date_due;	pair
borrower; vector
*>wait_list;};

 

 

重载输出操作符很简单:

 

ostream& operator<<(ostream &os,const CheckoutRecord &obj){	os<<"Book ID:"<
<
first<<" "<
second<<";"; os<

 

重载输入操作符复杂一点,因为我们要考虑用户输入错误的情况:

 

istream& operator>>(istream &in,CheckoutRecord &obj){	in>>obj.book_id;	if(in){		//when you typed newline,the new line was added to the 		//stream buffer, but "in>>obj.book_id" only reads the first double data and 		// left '\n' character still in the input stream buffer.		in.ignore(INT_MAX,'\n');		//Title may contain spaces		std::getline(in,obj.title);		in>>obj.date_borrowed>>obj.date_due>>\			obj.borrower.first>>obj.borrower.second;		while(in){			pair
*waiter=new pair
; in>>waiter->first; if(waiter->first=="end"){ delete waiter; break; } in>>waiter->second; obj.wait_list.push_back(waiter); } } else obj=CheckoutRecord(); return in;}

之所以费了很长时间,主要因为前面少写了一行代码:

in.ignore(INT_MAX,'\n');
导致后面的getline得到的是空行。

为什么要加上这样一行,我在注释中已经写明了原因。以前一直以为"cin>>whatever_data"这类输入语句,碰到换行或是空白这些分隔符的时候,会在流缓冲中去除有效输入后的下一个分隔符,原来这些分隔符都还在保存在缓冲中!输入语句的行为应该是这样,只会在流中消除在它要的有效输入的前面的分隔符字符,得到想要的输入后,后面又碰到一个分隔符,说明该输入数据结束。但不对想要的输入数据后面的分隔符做任何处理

不仅是对分隔符,对于输入错误时,"cin>>.."语句在输入终止后,使输入错误的字符让保留在流缓冲区内,这是一定要用cin.ignore来清理。

8.2节中的例子:

 

int ival;// read cin and test for only EOF; loop is excuted even if there are other IO failureswhile(cin >> ival, !cin.eof()){	if(cin.bad()) // input stream is corrupted; bail out 		throw runtime_error("IO stream corrupted!");	if(cin.fail()){		cerr << "Bad data, try again!";		cin.clear();		cin.ignore();			continue;	}}

不仅是C++的标准IO库,C中的标准IO库也用同样的问题——如果在scanf后面直接调用getline,也会得到空行。而且,对应cin.ignore(),可用fflush(stdin)来刷新缓冲区。

 

那哪些输入函数会自动处理有效输入后的换行符呢?

getline和fgets这类以行为单位的输入函数,会自动将已输入行的换行符从输入缓冲中去除。

 

这个教训再次告诉我们,使用函数接口的时候,一定要理清它们的行为细节。有时还要弄清它们的底层实现,才能更好地理解它们的行为

 

最后给出main函数和测试用例:

/*Sample Input:1001Miserable World201308201309Simon SmithMike aKris bTom  cBison dJumping eenderr_idMiserable World201308201309Simon SmithMike aKris bTom  cBis dJump eend*/int _tmain(int argc, _TCHAR* argv[]){	CheckoutRecord record;	cin>>record;	cout<<"========================================"<

 

 

 

 

转载于:https://www.cnblogs.com/james1207/p/3358101.html

你可能感兴趣的文章
对AngularJS进行性能调优的7个建议
查看>>
MVC后台数据赋值给前端JS对象
查看>>
KMP模板,最小循环节
查看>>
CSS - 背景图片拉伸的方法
查看>>
一些想法
查看>>
html email的问题
查看>>
结队编程
查看>>
谈谈2014年草根站长的出路
查看>>
C# 获取网站的 IIS 站点名称 ,获取站点当前连接数
查看>>
解决WCF 调用方未由服务器进行身份验证或消息包含无效或过期的安全上下文令牌...
查看>>
Codeforces 582C. Superior Periodic Subarrays(数学+计数)
查看>>
linux系统下创建oracle表空间和用户权限查询
查看>>
ThinkPHP函数详解:M方法
查看>>
VBS基础篇 - VBScript过程
查看>>
SQL Pass北京举办第三次线下活动,欢迎报名
查看>>
[组合数]求组合数的几种方法总结
查看>>
JDBC基础
查看>>
微信小程序尝鲜一个月现状分析
查看>>
c# 用OpenXmL读取.xlsx格式的Excel文件 返回DataTable
查看>>
Java使用JAVE获取MP4播放时长
查看>>