c++ primer(中文版第四版)第8章关于cin.clear(istream::failbit)的一个误区

抛出问题:

先附上书本中的例题程序代码

#include <iostream>

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

	return 0;
}

在输入正常时,没有什么问题。在输入字母时,就会一直打印“bad data, try again”这句话,效果如下所示:

解决问题方案:

我肯定不想让结果无限的打印,然后就开始查找原因,主要是因为没有清空输入流的缓存区的原因。所以我就对程序代码进行了一些修改,

#include <iostream>
#include <limits>

int main(){
	int ival;
	while (std::cin >> ival, !std::cin.eof()){
		if (std::cin.bad())
			throw std::runtime_error("IO stream corrupted");
		if (std::cin.fail()){
			std::cerr << "bad data, try again" << std::endl;
			//修正cin状态
			std::cin.clear(std::istream::failbit);
			//std::cin.clear();
			//清空缓存区
			//std::cin.sync();
			std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
			std::cout << std::cin.fail() << std::endl;
			continue;
		}
	}

	return 0;
}

但是这个时候还是看不到正确的结果,还是无限的打印。经过调试发现,是因为对failbit的设置没有起作用。但是用cin.clear()时就有效。虽然已经达到了我要的结果,但是为什么cin.clear(istream::failbit)没有效果呢,明明书上是这么写的啊。心里抱着各种怀疑的态度去stackoverflow上查查,果不其然有个人和我一样有这个问题,下面一个人的回答没怎么看懂,不过大体意思就是cin.clear(istream::failbit)不能真正的重置这个状态。

http://stackoverflow.com/questions/11246960/resetting-the-state-of-a-stream/11247530#11247530  (问题地址)

最后修改后的代码如下:

#include <iostream>
#include <limits>

int main(){
	int ival;
	while (std::cin >> ival, !std::cin.eof()){
		if (std::cin.bad())
			throw std::runtime_error("IO stream corrupted");
		if (std::cin.fail()){
			std::cerr << "bad data, try again" << std::endl;
			//修正cin状态
			//方法一:
			std::cin.clear(~std::istream::failbit & std::cin.rdstate());
			//方法二:
			//std::cin.clear();
			//清空缓存区
			//方法一:
			std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
			//方法二:
			//std::cin.sync();
			std::cout << std::cin.fail() << std::endl;
			continue;
		}
	}

	return 0;
}



时间: 2024-10-18 23:03:08

c++ primer(中文版第四版)第8章关于cin.clear(istream::failbit)的一个误区的相关文章

《C++ Primer》 第四版 第7章 函数

<C++ Primer> 第四版 第7章 函数 思维导图笔记 超级具体.很具体,图片版,有利于复习查看 http://download.csdn.net/detail/onlyshi/9479711

快速学习C++ primer(第四版)第一天

//1.17 //遍历数组a,计算其中负数的个数 int amount=0; for(int i=0;i<strlen(a);i++) if(a[i]<0) ++amount; //1.19 //每隔输10个值 for(int val=lower,count=1;val<=upper;++val,++count) { cout<<val<<" "; if(count%10==0) cout<<endl; } 快速学习C++ prim

《C++ Primer(中文版)(第5版)》斯坦利&#183;李普曼 (Stanley B. Lippman) (作者), 约瑟&#183;拉乔伊 (Josee Lajoie) (作者), 芭芭拉&#183;默 (Barbara E. Moo) (作者) azw3

内容简介: 这本久负盛名的C++经典教程,时隔八年之久,终迎来的重大升级.除令全球无数程序员从中受益,甚至为之迷醉的--C++ 大师 Stanley B. Lippman 的丰富实践经验,C++标准委员会原负责人Josée Lajoie 对C++标准的深入理解,以及C++ 先驱 Barbara E.Moo在C++教学方面的真知灼见外,更是基于全新的C++11标准进行了全面而彻底的内容更新.非常难能可贵的是,<C++ Primer中文版(第5版)>所有示例均全部采用C++11标准改写,这在经典升

C++ Primer中文版 (第5版)pdf

下载地址:网盘下载 C++ Primer中文版 (第5版)是久负盛名的 C 经典教程,时隔八年之久,终于迎来重大升级.除令全球无数程序员从中受益,甚至为之迷醉的--C 大师 Stanley B. Lippman 的丰富实践经验,C 标准委员会原负责人 Josée Lajoie 对C 标准的深入理解,以及C 先驱 Barbara E. Moo 在 C 教学方面的真知灼见外,更是基于全新的 C 11标准进行了全面而彻底的内容更新.非常难能可贵的是,<C Primer 中文版(第5版)>所有示例均全

C++ Primer Plus 第六版 第16章 string类和标准模板库

1.string实际上是模板具体化basic_string<char> 的一个typedef,有默认参数,所以省略了初始化参数 2.size_type是一个依赖于实现的整形 string将string::npos定义为字符串的最大长度 3.string类的构造函数P656 4.对于c-风格字符串,3种输入方法:cin>>   cin.getline(),cin.get 对于string   ,2种输入方法:cin>>,getline(cin,string对象) 5.st

Ajax本地跨域问题 Cross origin requests are only supported for HTTP(针对jQuery基础教程第四版第六章)

出现的问题: 解决的步骤: 谷歌浏览器出现的效果: 针对jQuery基础教程(第四版),第六章  成功: 原文地址:https://www.cnblogs.com/qinghui258/p/8432569.html

类作用域中名字查找的思考(《C++ primer》第四版P382)

1.问题的引入 1).观察以下第一块代码: #include <iostream> using namespace std; class Screen{ public: void test(){ dummy_fcn( ); } void dummy_fcn( ){ } }: 此代码编译无错误............... 2).再看以下第二块代码: #include <iostream> using namespace std; void test(){ dummy_fcn( );

『Java编程思想-第四版』第二章:一切都是对象

Java编程思想-第四版学习总结,此为第二章:一切都是对象. package com.w3cjava.second; @SuppressWarnings("all") public class Second { /** * Java编程思想(第四版) * 第2章 一切都是对象 * @param args */ public static void main(String[] args) { /** * 2.1 用引用操作对象 * 遥控器(引用)操作电视机(对象),改变音量,改变频道 *

C++primer(第四版)复习笔记—第一篇:基本语言

再次阅读primer一方面是为了查漏补缺,另一方面也是更加深入的理解C++的思想精髓.在此记录复习中记录的各知识细节及理解,以便后续温故之用. 第一张:快速入门 1. for语句: for(初始化语句:条件测试语句:条件修改表达式){ 语句体 } .执行顺序:初始化语句在最开始执行一次,然后执行条件测试语句,若成立则执行语句体:然后再执行条件修改表达式,再执行条件测试语句,成立则继续,反之则退出for语句. 2. if else语句缩进: if(0==i){ cout<<"i==0&