小心C++流的标志位

C++ Primer 第五版 P289 

linux环境

练习8.10

       编写程序,将来自一个文件中的行保存在一个vector<string>中。然后使用一个istringstream从vector读取数据元素,每次读取一个单词。

开始我是这么写的:

include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <string>
using namespace std;

int main(int argc, char *argv[])
{
	vector<string> str;
	string st;
	ifstream fi;		//define a file out stream

	fi.open(argv[1]);	//bind fstream to a file

	if(fi)			//select open success
	{
		while(getline(fi, st))		//according line get
			str.push_back(st);	//store in vector
	}
	else
	{
		cerr << "open " << argv[1] << "failed!" << endl;
		return -1;
	}
	//output the vector
	vector<string>::iterator it;
	
	for(it = str.begin(); it != str.end(); ++it)
	{
		istringstream read(*it);   //每次for循环都会重新创建一个istringstream对象
		string temp;

		while(read >> temp)		
			cout << temp << endl;
	}
	return 0;
}
要打开文件是myfile,内容是:

Hello, everyone!
My name is LiMing.
Today, I want to talk about how to study.

#./fream myfile

运行结果没问题。

下边想把istringstream read(*it);拿到for循环外面去定义,所以有如下程序:

include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <string>
using namespace std;

int main(int argc, char *argv[])
{
	vector<string> str;
	string st;
	ifstream fi;		//define a file out stream

	fi.open(argv[1]);	//bind fstream to a file

	if(fi)			//select open success
	{
		while(getline(fi, st))		//according line get
			str.push_back(st);	//store in vector
	}
	else
	{
		cerr << "open " << argv[1] << "failed!" << endl;
		return -1;
	}
	//output the vector
	vector<string>::iterator it;
	
        istringstream read;
	for(it = str.begin(); it != str.end(); ++it)
	{
		read.str(*it);     //每次for循环都会把vector的string元素拷贝到istringstream里
		string temp;

		while(read >> temp)		
			cout << temp << endl;
	}
	return 0;
}
#./fream myfile

很奇怪,为什么其他的没有输出来。后来看到网上说必须在循环最后加上clear()才行。于是,焕然大悟:

        istringstream read;
	for(it = str.begin(); it != str.end(); ++it)
	{
		read.str(*it);
		string temp;

		while(read >> temp)		
			cout << temp << endl;
		read.clear();
	}
因为while循环读到string的最后时结束,(也就是输出了Hello, everyone! 后)istringstream对象的eofbit标志会置位,后边的for循环里拷贝到read里的string都会因为eofbit置位而不进入while循环,所以无法输出接下来的单词。 因此当一次for循环结束(一个string输出完毕后)时,clear()一下标志位,下次就可以读出新的string了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值