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;
}


猜你喜欢

转载自blog.csdn.net/u011248694/article/details/45584985