C++ 將資料寫入鏈表,將鏈表寫入檔案,再將檔案中的內容讀出__C++
來源:互聯網
上載者:User
就算世界荒蕪,總有一個人,他會是你的信徒。 ----《獨木舟裡的星星》
第一步:建立一個節點 template < typename T > class Node { public: Node (T data) { m_data = data; m_pNext = NULL ; }
const T & getData () { return m_data; }
Node < T > * & getNext () { return m_pNext; } private: T m_data; Node * m_pNext; }; 這裡用到了類模板,因為這裡的資料部分類型無法確定。
第二步:建立鏈表 template < typename T > class List { public: List () { m_iLen = 0 ; m_pFirstNode = NULL ; }
Node < T >* getFirstNode () { return m_pFirstNode; }
int getListLen () { return m_iLen; }
void insert (T data) { Node < T > * node = new Node < T > (data); node-> getNext () = m_pFirstNode; m_pFirstNode = node; m_iLen ++ ; }
void display () { Node < T > * tmp = m_pFirstNode; for ( int i = 0 ; i < m_iLen; i ++ ) { cout << tmp-> getData () << endl; tmp = tmp-> getNext (); } }
private: int m_iLen; Node < T > * m_pFirstNode; }; 一般習慣將鏈表頭定義的與其他節點不同,鏈表頭可以放很多資訊,例如:鏈表長度、作者、修改人、建立日期等等,當後面節點加入的時候不會每個節點都有這些資訊。
。。。可以在主函數中試一下鏈表。。。 int main(void) { List<int> intList; intList.insert(2); intList.insert(1); intList.insert(5); intList.insert(3); intList.insert(4); cout << "列印鏈表" << endl; intList.display();
第四步:
鏈表寫好後,我們將鏈表寫入檔案中 fstream file1; file1.open("int.txt"); file1 << intList; 將檔案以讀寫的方式開啟,記得要提前建立檔案int.txt,因為以讀寫方式開啟檔案的時候,如果檔案不存在,程式不會自動建立。同樣,以唯讀開啟也是一樣,只有以唯寫開啟的時候才會自動建立。如果僅僅這樣寫,編譯的時候肯定
無法通過 ,因為無法將一個鏈表類型的資料直接寫入檔案。我們需要將
<<運算子多載。
重載運算子: << template<typename T> fstream &operator << (fstream &file, List<T> &list) { Node<T> *tmp = list.getFirstNode(); int len = list.getListLen(); for(int i = 0; i < len; i++) { file << tmp->getData(); tmp = tmp->getNext(); } return file; } 寫完後,再執行file1.intList; 就不會報錯了。
第五步:從檔案中讀取資料到鏈表 file1.seekg(0, ios_base::beg); cout << "--------讀取檔案裡的鏈表------------" << endl; List<int> intList2; int data = 0; while(1) { file1 >> data; intList2.insert(data); if(file1.eof()) { break; } } intList2.display(); file1.close(); 思路很簡單,首先將檔案的讀寫位置設定到首部,因為我們在寫入檔案的時候,讀寫位置到了最後,這時候直接讀是讀不到資料的。然後將檔案裡的內容讀到臨時變數data中,然後插入的時候調用有參建構函式,輸入參數data,產生新鏈表。讀取完退出,最後列印顯示。
上面的鏈表只針對一般的資料類型有效,如果我們的資料部分是自己構造的類呢。
第一步:建立一個類(以student為例) class Student { public: Student ( int id = 1000 , string name = " " , float score = 0.0f ) { m_iId = id; m_strName = name; m_fScore = score; }
friend ostream & operator << (ostream & out, const Student & stu);
private: int m_iId; string m_strName; float m_fScore; };
第二步:重載運算子 << ostream & operator << (ostream & out, const Student & stu) { out << " " << stu. m_iId << " " << stu. m_strName << " " << stu. m_fScore ; } 這裡重載是因為1、列印的時候無法直接直接輸入一個Student類型,即:cout << stu 是無法直接實現的, 2、寫入檔案的時候同樣無法直接寫入一個Student類型。但為什麼只重載ostream中的<<就可以同時實現兩個呢。因為fstream繼承了iostream,而iostream又繼承了istream和ostream。關係如下圖:
這之後的操作大同小異,大家可以自行理解。 下面是全代碼,以及列印結果:
#include <iostream> #include <fstream> using namespace std ;
class Student { public: Student ( int id = 1000 , string name = " " , float score = 0.0f ) { m_iId = id; m_strName = name; m_fScore = score; }
friend ostream & operator << (ostream & out, const Student & stu); //friend fstream &operator << (fstream &file, const Student &stu); private: int m_iId; string m_strName; float m_fScore; };
ostream & operator << (ostream & out, const Student & stu) { out << " " << stu. m_iId << " " << stu. m_strName << " " << stu. m_fScore ; }
template < typename T > class Node { public: Node (T data) { m_data = data; m_pNext = NULL ; }
const T & getData