istream_iterator 在<iterator>头文件的定义中
定义istream_iterator变量的方法为
istream_iterator<T> in(strm); (其中T指明此istream_iterator的输入类型 , strm为istream_iterator指向的流)
提供了输入操作符(>>)和 输出操作符 (<<)的任何类型都可以创建 istream_iterator 对象和ostream_iteratorcfq对象,即对自己的类重载了这两个函数:
istream &operator >> (istream &is, &MyClass c);
和 ostream &operator << (ostream &os , const &MyClass c);
1. 若strm为空时,即比如istream<T> in();时, 此时变量in 就相当于指向EOF标志的iterator了
如图如下定义: (下文的eoff是我故意这样写的,只是为了让大家明白这个名字随便起都行)
istream_iterator<T> eoff ;
发现eoff的私有变量中_Myistr为0x000000000;
再看看一个定义: (注意:test.txt的内容为10(EOF) )
ifstream infile("f:\\test.txt"); istream_iterator<int> input(infile);
再用vs2008调试时查看:
大家发现没有:input变量的私有成员_Myistr不为0了! 且私有成员_Myval正好为10(即文件中的第一个整型数)
现在在执行下一行代码:
++input;
再用VS2008看看input的成员:
++input后,其私有成员_Myistr变为0x00000000了!和之前定义的eoff变量一样了!
再执行下一行看看会输出什么:
cout<<(in == eoff ? "EOF" : "others")<<endl;显然此时的in == eoff 成立,结果输出的是 "EOF"
现在我们知道了copy(input,eoff,back_inserter(ivec)这么用法的原因了吧。 因为copy函数是通过input先与eoff比较是否相等,若不等则将其解引用(*input)插入到ivec的最后
然后再自加1,再与eoff比较. 直到与eoff比较相等时结束! 所以用未用流初始化的istream_iterator作为哨兵.
copy(istream_iterator<int>(cin),istream_iterator<int>(),back_inserter(ivec)也是一样的情况。 需要结束时按下ctrl+z产生EOF标志 ^z
完整程序如下:
#include <iostream> #include <vector> #include <fstream> #include <iterator> //istream_iterator,ostream_iterator,back_inserter #include <algorithm> //copy #include <Windows.h> //system using namespace std; int main() { istream_iterator<int> eoff; ifstream infile("f:\\test.txt"); //运行前,请让f:\\test.txt里面只有一个整数 istream_iterator<int> input(infile); cout<<"the first element:"<<*input<<endl; ++input; cout<<(input == eoff ? "EOF" : "others")<<endl; cout<<"*******************"<<endl; cout<<"请输入整数,按ctrl+z结束输入:"<<endl; vector<int> ivec; copy(istream_iterator<int>(cin),istream_iterator<int>(),back_inserter(ivec)); //下句为将ivec内容输出屏幕 copy(ivec.begin(),ivec.end(),ostream_iterator<int>(cout,"\t")); system("pause"); }
ps: istream_iterator 和 ostream_iterator 都没有定义自减运算,即 --input; 是错误的!
2. 注意了如果对于istream_iterator<int> 型,如果文件里面是为字母的话,input会如何呢?
在此之前,请把f:\test.txt的加一个字母看什么情况 即内容为: 10 sfd(EOF)
istream_iterator<int> eoff; ifstream infile("f:\\test.txt"); //运行前,请让f:\\test.txt里面只有一个整数 istream_iterator<int> input(infile); cout<<"the first element:"<<*input<<endl; ++input;
我们看看现在的input的成员:
input遇到字母时,_Myistr也变为0x00000000了。那么是不说
cout<<(input == eoff ? "EOF" : "others")<<endl;也会输入“EOF”,即input == eoff呢? 答案确实是肯定的!
其实此时的cin.good()也为false了. 大家可以加一行代码试试:cout<<cin.good()<<endl;
现在我们知道了,当只需要整型时,使用istream_iterator<int> (cin)输入时,也可以输入一个非int型的字母来终结输入。
对于ostream_iterator<T> ouput(strm,"xxx");也是一样,只是现在的output为左值为:
例如:
ostream_iterator<int> output(cout," : "); *output = 5; *output = 6;
或者这样写
ostream_iterator<int> output(cout," : "); *output++ = 5; *output++ = 6;其结果都是:5 : 6 output每次解引用 *output后赋值后,都会使自己自加1 。
也就是说不用自己使用 *output++ 的方法了。
总之:
这两句是最好用的了:
copy(istream_iterator<int>(cin),istream_iterator<int>(),back_inserter(ivec)); //下句为将ivec内容输出屏幕 copy(ivec.begin(),ivec.end(),ostream_iterator<int>(cout,"\t"));
输入那句更好的是
vector<int> ivec(istream_iterator<int>(cin),istream_iterator<int>());
这句更简洁.
若写的有问题,请各位大侠指教。转载请注明出处.