iterator和ostream

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> //systemusing 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;运行这几句后,istream_iterator<int> input(infile)应该只能指向整型,但现在为字母了,会如何呢?

我们看看现在的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 : 6output每次解引用 *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>());

这句更简洁.

若写的有问题,请各位大侠指教。

转载请注明出处.

灯红酒绿的城市,登上楼顶,俯视万家灯火,

iterator和ostream

相关文章:

你感兴趣的文章:

标签云: