TCPL C++迭代器的用法 用作引數傳遞 讀寫檔案
阿新 • • 發佈:2019-02-06
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