1. 程式人生 > >TCPL C++迭代器的用法 用作引數傳遞 讀寫檔案

TCPL C++迭代器的用法 用作引數傳遞 讀寫檔案

C++資料流迭代器(iterators)一般不直接使用,而是用做某些演算法的引數。這些演算法多是STL中的演算法,是用C習慣了的朋友,應該會覺得這個有點不需太習慣,但是這就是C++的方法,據C++之父Bejarne的說法就是程式碼要elegant(優雅)!

多使用資料流,並熟悉這個概念的話,我覺得還是挺好的概念的。

例如下面是一個簡單的程式:

int main()
{
   string from, to;
   cin >> from >> to; //讀取原始檔和目標檔案
   ifstream is {from}; // 原始檔作為輸入流
   istream_iterator<string> ii {is}; //定義其輸入流迭代器
   istream_iterator<string> eos {}; //作為結束符
   ofstream os{to}; //定義輸出流
   ostream_iterator<string> oo {os,"\n"}; //定義輸出流的迭代器
   vector<string> b {ii,eos}; //用輸入流迭代器和其結束符初始化vector b
   sort(b.begin(),b.end()); //STL中的標準排序演算法,對b進行排序
   unique_copy(b.begin(),b.end(),oo); //STL中的演算法,copy到輸出流中去,記得前面我們定義了輸出流是ofstream os{to},就是說輸出流和to目標檔案繫結在一起了,所以copy到輸出流中,其實就是copy到了to檔案裡面了。
   return !is.eof() || !os; //最後的輸出狀態如果不是eof結束符或者正常狀態os,就返回錯誤
}

檔案輸入流(ifstream)是一個可以繫結一個檔案的流, ofstream是一個可以繫結輸出檔案的流。ofstream_iterator的第二個引數,如:ofstream_iterator<string> oo{os, "\n"},的"\n"是作為一個定界符,也就是用來分隔各個輸出值的。

看C++之父的書的朋友都知道,他老人家經常說的就是elegant,優雅的程式碼,清潔,簡短的程式碼,他從來不喜歡那麼ugly,verbose 醜陋和冗長的程式碼,所以下面是更加elegant,short的程式碼:

int main()
{
   string from, to;
   cin >> from >> to; 
   ifstream is {from}; 
   ofstream os {to}; 
   set<string> b {istream_iterator<string>{is},istream_iterator<string>{}}; 
   copy(b.begin(),b.end(),ostream_iterator<string>{os,"\n"}); 
   return !is.eof() || !os; 
}

這裡之所以簡短了,是因為用了set代替了vector。set容器的特徵是不保持同樣的資料,所以這裡只用copy就可以了,不用unque_copy了。第二個特徵是set容器的資料自動排序好的了,所以這裡不用sort排序。

這裡set<string> b這句也更加難理解了,因為輸入流迭代器和其結束符都只是用一次就可以了,所以這裡也只用了臨時物件的概念,這個概念就是建立一個物件,但是沒有物件名字,所以只有呼叫時候可以是用,呼叫完之後也就不存在這個物件了。

reference:

The C++ Programming Language 4ed Chapter04