小心C++流的标志位

来源:互联网 发布:仙界网络直播间txt笔下 编辑:程序博客网 时间:2024/05/22 00:53

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 streamfi.open(argv[1]);//bind fstream to a fileif(fi)//select open success{while(getline(fi, st))//according line getstr.push_back(st);//store in vector}else{cerr << "open " << argv[1] << "failed!" << endl;return -1;}//output the vectorvector<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 streamfi.open(argv[1]);//bind fstream to a fileif(fi)//select open success{while(getline(fi, st))//according line getstr.push_back(st);//store in vector}else{cerr << "open " << argv[1] << "failed!" << endl;return -1;}//output the vectorvector<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了。

0 0
原创粉丝点击