stream_iterator、ostream_iterator 使用初探

來源:互聯網
上載者:User

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

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.