STL定義了供輸入及輸出的iostream iterator類,稱為 istream_iterator和ostream_iterator,分別支援單一型別的元素的讀取和寫入。
使用方法:
1.包含標頭檔: #include <iterator> using namespace std;
2.像使用其他iterator一樣使用istream_iterator和 ostream_iterator。如:
使用一對“串連至標準輸入”的iterator用於標示元素範圍:
// 將is定義為一個“串連至標準輸入裝置”的istream_iterator
istream_iterator<string> is(cin);
// 定義istream_iterator時不為它指定istream對象,它即代表了end-of-file。
istream_iterator<string> eof;
ostream_iterator<string> os(cout, " ");
除了“串連至標準輸入”外,還可以串連至其他裝置,如檔案:
#include <fstream> using namespace std; ifstream in_file("in.txt"); ofstream out_file("in.txt"); if ( !in_file || !out_file ) { cerr << "failed to open the necessary file! /n"; return -1; } istream_iterator<string> is(in_file); istream_iterator<string> eof; ostream_iterator<string> os(out_file, " ");
***********************************************************************************************
#include <iostream> #include <iterator> #include <string> #include <vector> #include <fstream> #include <algorithm> using namespace std; int main() { // 1. 標準輸入輸出操作。 istream_iterator<string> is(cin); istream_iterator<string> eof; vector<string> text; // 將標準輸入的內容複寫至text中。 由於使用的是vector,故使用back_inserter() copy(is, eof, back_inserter(text)); // do something. sort(text.begin(), text.end()); // 輸出至標準輸出。 ostream_iterator<string> os(cout, " "); copy(text.begin(), text.end(), os); // 2. 非標準輸入輸出操作:檔案讀寫操作。 ifstream in_file("in.txt"); ofstream out_file("in.txt"); if ( !in_file || !out_file ) { cerr << "failed to open the necessary file! /n"; return -1; } istream_iterator<string> is2(in_file); istream_iterator<string> eof2; vector<string> text2; copy(is2, eof2, back_inserter(text2)); sort(text2.begin(), text2.end()); ostream_iterator<string> os2(out_file, " "); copy(text2.begin(), text2.end(), os2); return 0; }
************************************************************************************
istream_iterator常見錯誤
1. 錯誤原碼
以下原代碼不能通過編譯:
ifstream ifs("test.txt");
istream_iterator<string> ibeg(ifs);
istream_iterator<string> iend();
vector<string> vec(ibeg, iend);
對於vec的構造編譯出錯:
error: no matching function for call to `std::vector<std::string, std::allocator<std::string> >::vector(std::istream_iterator<std::string, char, std::char_traits<char>, ptrdiff_t>&, std::istream_iterator<std::string, char, std::char_traits<char>, ptrdiff_t>
(&)())'
原來它把iend當作了一個函數。去掉iend後面的括弧就行了:
2. 正確的完整代碼
#include <iostream>#include <iterator>#include <fstream>#include <vector>#include <algorithm>using namespace std;int main(){ ifstream ifs("test.txt"); istream_iterator<string> ibeg(ifs); istream_iterator<string> iend; vector<string> vec(ibeg, iend); copy(vec.begin(), vec.end(),ostream_iterator<string>(cout, "\n")); return 0;}
3. 直接內嵌出錯
就像在copy函數中一樣,並不需要定義ibeg, iend, 應該可以在vector的建構函式中嵌入,如下:
vector<string> vec(istream_iterator<string>(ifs),istream_iterator<string>);
以上代碼當在copy中調用vec.begin(), vec.end()時,就會編譯報錯:
error: request for member `begin' in `vec', which is of non-class type `std::vector<std::string, std::allocator<std::string> > ()(std::istream_iterator<std::string, char, std::char_traits<char>, ptrdiff_t>, std::istream_iterator<std::string, char, std::char_traits<char>,
ptrdiff_t>)'
error: request for member `end' in `vec', which is of non-class type `std::vector<std::string, std::allocator<std::string> > ()(std::istream_iterator<std::string, char, std::char_traits<char>, ptrdiff_t>, std::istream_iterator<std::string, char, std::char_traits<char>,
ptrdiff_t>)'
看來編譯器將vec當作了一個函數,而不是一個vector類。
其中istream_iterator<string>(ifs)
的括弧被編譯器忽略了,成為
vector<string> vec(istream_iterator<string> ifs,
istream_iterator<string>);
等同於:
vector<string> fun(istream_iterator<string> x,
istream_iterator<string> y);
4. 訪止編譯器誤解
就像在加減乘除中用括弧指定運算順序一樣,這裡也要用括弧將構造的臨時參數括起來,訪止編譯器將它們誤解為函數中的參數聲明。
同時還要修正一個錯誤,vec建構函式中的第二個參數構造是錯誤的,應該加個括弧構造一個臨時變數。不然對
istream_iterator<string>);
報錯:
error: expected primary-expression before ')' token
因為它只是一個型別宣告,而不是一個基本運算式(primary-expression)。
正確的方法如下:
vector<string> vec((istream_iterator<string>(ifs)),
istream_iterator<string>());
或
vector<string> vec((istream_iterator<string>(ifs)),
(istream_iterator<string>()));
該種方法雖然可行,但還是不用為好,以免某些編譯器不支援,同時也增加代碼理解難度,而且在更複雜的情形中,這一招也無法解決問題。還是第5種簡化方法比較合適
提示:不管需不需要,稍微複雜一點的運算式都用括弧括起來。免得人閱讀時出錯,或者編譯器理解時出錯。
5. 另一種簡化方法
ibeg, iend的定義可以合為一行,可能比內嵌式表達方法更清晰:
istream_iterator<string> ibeg(ifs), iend;
vector<string> vec(ibeg, iend);
http://blog.csdn.net/rickliuxiao/article/details/6201835
http://www.cppblog.com/jinq0123/archive/2007/12/12/istream_iterator_ErrorMsg.html