到目前為止,我們已經使用了 <b>iostream</b> 标準庫,它提供了 <b>cin</b> 和 <b>cout</b> 方法分别用于從标準輸入讀取流和向标準輸出寫入流。
本教程介紹如何從檔案讀取流和向檔案寫入流。這就需要用到 C++ 中另一個标準庫 <b>fstream</b>,它定義了三個新的資料類型:
資料類型
描述
ofstream
該資料類型表示輸出檔案流,用于建立檔案并向檔案寫入資訊。
ifstream
該資料類型表示輸入檔案流,用于從檔案讀取資訊。
fstream
該資料類型通常表示檔案流,且同時具有 ofstream 和 ifstream 兩種功能,這意味着它可以建立檔案,向檔案寫入資訊,從檔案讀取資訊。
要在 C++ 中進行檔案處理,必須在 C++ 源代碼檔案中包含頭檔案 <iostream> 和 <fstream>。
在從檔案讀取資訊或者向檔案寫入資訊之前,必須先打開檔案。<b>ofstream</b> 和 <b>fstream</b> 對象都可以用來打開檔案進行寫操作,如果隻需要打開檔案進行讀操作,則使用 <b>ifstream</b> 對象。
下面是 open() 函數的标準文法,open() 函數是 fstream、ifstream 和 ofstream 對象的一個成員。
在這裡,<b>open()</b> 成員函數的第一參數指定要打開的檔案的名稱和位置,第二個參數定義檔案被打開的模式。
模式标志
ios::app
追加模式。所有寫入都追加到檔案末尾。
ios::ate
檔案打開後定位到檔案末尾。
ios::in
打開檔案用于讀取。
ios::out
打開檔案用于寫入。
ios::trunc
如果該檔案已經存在,其内容将在打開檔案之前被截斷,即把檔案長度設為 0。
您可以把以上兩種或兩種以上的模式結合使用。例如,如果您想要以寫入模式打開檔案,并希望截斷檔案,以防檔案已存在,那麼您可以使用下面的文法:
類似地,您如果想要打開一個檔案用于讀寫,可以使用下面的文法:
當 C++ 程式終止時,它會自動關閉重新整理所有流,釋放所有配置設定的記憶體,并關閉所有打開的檔案。但程式員應該養成一個好習慣,在程式終止前關閉所有打開的檔案。
下面是 close() 函數的标準文法,close() 函數是 fstream、ifstream 和 ofstream 對象的一個成員。
在 C++ 程式設計中,我們使用流插入運算符( << )向檔案寫入資訊,就像使用該運算符輸出資訊到螢幕上一樣。唯一不同的是,在這裡您使用的是 <b>ofstream</b> 或 <b>fstream</b> 對象,而不是 <b>cout</b> 對象。
在 C++ 程式設計中,我們使用流提取運算符( >> )從檔案讀取資訊,就像使用該運算符從鍵盤輸入資訊一樣。唯一不同的是,在這裡您使用的是 <b>ifstream</b> 或 <b>fstream</b> 對象,而不是 <b>cin</b> 對象。
下面的 C++ 程式以讀寫模式打開一個檔案。在向檔案 afile.dat 寫入使用者輸入的資訊之後,程式從檔案讀取資訊,并将其輸出到螢幕上:
#include <fstream>
#include <iostream>
using namespace std;
int main ()
{
char data[100];
// 以寫模式打開檔案
ofstream outfile;
outfile.open("afile.dat");
cout << "Writing to the file" << endl;
cout << "Enter your name: ";
cin.getline(data, 100);
// 向檔案寫入使用者輸入的資料
outfile << data << endl;
cout << "Enter your age: ";
cin >> data;
cin.ignore();
// 再次向檔案寫入使用者輸入的資料
// 關閉打開的檔案
outfile.close();
// 以讀模式打開檔案
ifstream infile;
infile.open("afile.dat");
cout << "Reading from the file" << endl;
infile >> data;
// 在螢幕上寫入資料
cout << data << endl;
// 再次從檔案讀取資料,并顯示它
infile.close();
return 0;
}
當上面的代碼被編譯和執行時,它會産生下列輸入和輸出:
上面的執行個體中使用了 cin 對象的附加函數,比如 getline()函數從外部讀取一行,ignore() 函數會忽略掉之前讀語句留下的多餘字元。
<b>istream</b> 和 <b>ostream</b> 都提供了用于重新定位檔案位置指針的成員函數。這些成員函數包括關于 istream 的 <b>seekg</b>("seek get")和關于 ostream 的 <b>seekp</b>("seek put")。
seekg 和 seekp 的參數通常是一個長整型。第二個參數可以用于指定查找方向。查找方向可以是 <b>ios::beg</b>(預設的,從流的開頭開始定位),也可以是 <b>ios::cur</b>(從流的目前位置開始定位),也可以是 <b>ios::end</b>(從流的末尾開始定位)。
檔案位置指針是一個整數值,指定了從檔案的起始位置到指針所在位置的位元組數。下面是關于定位 "get" 檔案位置指針的執行個體:
// 定位到 fileObject 的第 n 個位元組(假設是 ios::beg)
fileObject.seekg( n );
// 把檔案的讀指針從 fileObject 目前位置向後移 n 個位元組
fileObject.seekg( n, ios::cur );
// 把檔案的讀指針從 fileObject 末尾往回移 n 個位元組
fileObject.seekg( n, ios::end );
// 定位到 fileObject 的末尾
fileObject.seekg( 0, ios::end );