ストリームイテレータ

http://www.geocities.jp/ky_webid/cpp/library/014.html

出力や入力に対してイテレータを使って値のやり取りができます。そのようなイテレータのことをストリームイテレータを言うようです。

まずは出力ストリームの動作を確認してみます。

#include <iostream>
#include <iterator>
using namespace std;

int main () {
    
    ostream_iterator<int> oit( cout, "\n" );
    
    // 出力ストリームにデータを送る
    *oit = 10;
    *oit = 20;
    *oit = 30;
    
    return 0;
}
$ main
10
20
30

表示されました。

コンストラクタの第一引数には使用するストリームの種類。今回はcoutをそのまま渡しています。

で第二引数はデリミタと呼ばれるもので、要は区切文字ですね。イテレータへ代入した値+デリミタが出力されるといった感じです。

#include <iostream>
#include <iterator>
using namespace std;

int main () {
    
    // デリミタを--にしてみる
    ostream_iterator<int> oit( cout, "--" );
    
    *oit = 10;
    *oit = 20;
    *oit = 30;
    
    return 0;
}
10--20--30--

と表示されます。


次に入力ストリームの動作を確認してみます。

#include <iostream>
#include <iterator>
using namespace std;

int main () {
    
    istream_iterator<int> iit( cin );
    istream_iterator<int> iit_eof;
    
    while ( iit != iit_eof ) {
        cout << "cin = " << *iit << endl;
            ++iit;
    }
    
    return 0;
}
$ main
100 200
cin = 100
cin = 200
z

こんな感じになります。

まずコンストラクタに使用する入力ストリームを渡します。今回はcinを渡しています。次に引数無しでインスタンス化した変数を用意します。これは入力の最後、つまりEOFを表します。

あとはwhileで入力の最後が来るまでループで入力を受付けするという処理になっています。

そして注目すべき点は、「z」を入力したらEOF扱いになり、ループを抜けて終了している点です。

これはistream_iteratorのテンプレート引数にint型を指定しているので、それ以外のデータが入力されたら終了するという処理になっているからです。便利ですね。

文字列も入力させたければstring型あたりを使うと良いのでしょうか。

#include <iostream>
#include <iterator>
#include <string>
using namespace std;

int main () {
    
    istream_iterator<string> iit( cin );
    istream_iterator<string> iit_eof;
    
    while ( iit != iit_eof ) {
        cout << "cin = " << *iit << endl;
            ++iit;
    }
    
    return 0;
}
$ main
abc 100
cin = abc
cin = 100
^Z

うまく動いていますね。(Crtl+Zの入力は前にC言語で習ったデータを終端を表す入力です。参考→http://www.geocities.jp/ky_webid/c/027.html