檔案 i/o 在c++中比烤蛋糕簡單多了。 在這篇文章裡,我會詳細解釋ascii和二進位制檔案的輸入輸出的每個細節,值得注意的是,所有這些都是用c++完成的。
一、ascii 輸出
為了使用下面的方法, 你必須包含標頭檔案(譯者注:在標準c++中,已經使用取代< fstream.h>,所有的c++標準標頭檔案都是無字尾的。)。這是 的乙個擴充套件集, 提供有緩衝的檔案輸入輸出操作. 事實上, 已經被包含了, 所以你不必包含所有這兩個檔案, 如果你想顯式包含他們,那隨便你。我們從檔案操作類的設計開始, 我會講解如何進行ascii i/o操作。如果你猜是"fstream," 恭喜你答對了! 但這篇文章介紹的方法,我們分別使用"ifstream"?和 "ofstream" 來作輸入輸出。
如果你用過標準控制台流"cin"?和 "cout," 那現在的事情對你來說很簡單。 我們現在開始講輸出部分,首先宣告乙個類物件。ofstream fout;
這就可以了,不過你要開啟乙個檔案的話, 必須像這樣呼叫ofstream::open()。
fout.open("output.txt");
你也可以把檔名作為構造引數來開啟乙個檔案.
ofstream fout("output.txt");
這是我們使用的方法, 因為這樣建立和開啟乙個檔案看起來更簡單. 順便說一句, 如果你要開啟的檔案不存在,它會為你建立乙個, 所以不用擔心檔案建立的問題. 現在就輸出到檔案,看起來和"cout"的操作很像。 對不了解控制台輸出"cout"的人, 這裡有個例子。
int num = 150;
char name = "john doe";
fout << "here is a number: " << num << "\n";
fout << "now here is a string: " << name << "\n";
現在儲存檔案,你必須關閉檔案,或者回寫檔案緩衝. 檔案關閉之後就不能再操作了, 所以只有在你不再操作這個檔案的時候才呼叫它,它會自動儲存檔案。 回寫緩衝區會在保持檔案開啟的情況下儲存檔案, 所以只要有必要就使用它。回寫看起來像另一次輸出, 然後呼叫方法關閉。像這樣:
fout << flush; fout.close();
here is a number: 150 now here is a string: john doe
很簡單吧! 現在繼續檔案輸入, 需要一點技巧, 所以先確認你已經明白了流操作,對 "<<" 和">>" 比較熟悉了, 因為你接下來還要用到他們。繼續…
二、ascii 輸入
輸入和"cin" 流很像. 和剛剛討論的輸出流很像, 但你要考慮幾件事情。在我們開始複雜的內容之前, 先看乙個文字:
12 gamedev 15.45 l this is really awesome!
為了開啟這個檔案,你必須建立乙個in-stream物件,?像這樣。
ifstream fin("input.txt");
現在讀入前四行. 你還記得怎麼用"<<" 操作符往流裡插入變數和符號吧?好,?在 "<<" (插入)?操作符之後,是">>" (提取) 操作符. 使用方法是一樣的. 看這個**片段.
int number;
float real;
char letter, word[8];
fin >> number; fin >> word; fin >> real; fin >> letter;
也可以把這四行讀取檔案的**寫為更簡單的一行。
fin >> number >> word >> real >> letter;
它是如何運作的呢? 檔案的每個空白之後, ">>" 操作符會停止讀取內容, 直到遇到另乙個》操作符. 因為我們讀取的每一行都被換行符分割開(是空白字元), ">>" 操作符只把這一行的內容讀入變數。這就是這個**也能正常工作的原因。但是,可別忘了檔案的最後一行。
this is really awesome!
如果你想把整行讀入乙個char陣列, 我們沒辦法用">>"?操作符,因為每個單詞之間的空格(空白字元)會中止檔案的讀取。為了驗證:
char sentence[101]; fin >> sentence;
我們想包含整個句子, "this is really awesome!" 但是因為空白, 現在它只包含了"this". 很明顯, 肯定有讀取整行的方法, 它就是getline()。這就是我們要做的。
fin.getline(sentence, 100);
這是函式引數. 第乙個引數顯然是用來接受的char陣列. 第二個引數是在遇到換行符之前,陣列允許接受的最大元素數量. 現在我們得到了想要的結果:「this is really awesome!」。
你應該已經知道如何讀取和寫入ascii檔案了。但我們還不能罷休,因為二進位制檔案還在等著我們。
三、二進位制 輸入輸出
二進位制檔案會複雜一點, 但還是很簡單的。首先你要注意我們不再使用插入和提取操作符(譯者注:<< 和 >> 操作符). 你可以這麼做,但它不會用二進位制方式讀寫。你必須使用read() 和write() 方法讀取和寫入二進位制檔案. 建立乙個二進位制檔案, 看下一行。
ofstream fout("file.dat", ios::binary);
這會以二進位制方式開啟檔案, 而不是預設的ascii模式。首先從寫入檔案開始。函式write() 有兩個引數。 第乙個是指向物件的char型別的指標, 第二個是物件的大小(譯者注:位元組數)。 為了說明,看例子。
int number = 30; fout.write((char *)(&number), sizeof(number));
第乙個引數寫做"(char *)(&number)". 這是把乙個整型變數轉為char *指標。如果你不理解,可以立刻翻閱c++的書籍,如果有必要的話。第二個引數寫作"sizeof(number)". sizeof() 返回物件大小的位元組數. 就是這樣!
二進位制檔案最好的地方是可以在一行把乙個結構寫入檔案。 如果說,你的結構有12個不同的成員。 用ascii?檔案,你不得不每次一條的寫入所有成員。 但二進位制檔案替你做好了。 看這個。
struct object obj;
obj.number = 15;
obj.letter = 『m』;
fout.write((char *)(&obj), sizeof(obj));
這樣就寫入了整個結構! 接下來是輸入. 輸入也很簡單,因為read()?函式的引數和 write()是完全一樣的, 使用方法也相同。
ifstream fin("file.dat", ios::binary); fin.read((char *)(&obj), sizeof(obj));
我不多解釋用法, 因為它和write()是完全相同的。二進位制檔案比ascii檔案簡單, 但有個缺點是無法用文字編輯器編輯。 接著, 我解釋一下ifstream 和ofstream 物件的其他一些方法作為結束.
四、更多方法
我已經解釋了ascii檔案和二進位制檔案, 這裡是一些沒有提及的底層方法。
檢查檔案
你已經學會了open() 和close() 方法, 不過這裡還有其它你可能用到的方法。
方法good() 返回乙個布林值,表示檔案開啟是否正確。
類似的,bad() 返回乙個布林值表示檔案開啟是否錯誤。 如果出錯,就不要繼續進一步的操作了。
最後乙個檢查的方法是fail(), 和bad()有點相似, 但沒那麼嚴重。
讀檔案方法get() 每次返回乙個字元。
方法ignore(int,char) 跳過一定數量的某個字元, 但你必須傳給它兩個引數。第乙個是需要跳過的字元數。 第二個是乙個字元, 當遇到的時候就會停止。 例子,
fin.ignore(100, 『\n』);
會跳過100個字元,或者不足100的時候,跳過所有之前的字元,包括 『\n』。
方法peek() 返回檔案中的下乙個字元, 但並不實際讀取它。所以如果你用peek() 檢視下乙個字元, 用get() 在peek()之後讀取,會得到同乙個字元, 然後移動檔案計數器。
方法putback(char) 輸入字元, 一次乙個, 到流中。我沒有見到過它的使用,但這個函式確實存在。
寫檔案只有乙個你可能會關注的方法.?那就是 put(char), 它每次向輸出流中寫入乙個字元。
開啟檔案
當我們用這樣的語法開啟二進位制檔案:
ofstream fout("file.dat", ios::binary);
"ios::binary"是你提供的開啟選項的額外標誌. 預設的, 檔案以ascii方式開啟, 不存在則建立, 存在就覆蓋. 這裡有些額外的標誌用來改變選項。
ios::ate 把檔案標誌放在末尾而非起始。
ios::trunc 預設. 截斷並覆寫檔案。
ios::nocreate 檔案不存在也不建立。
ios::noreplace 檔案存在則失敗。
檔案狀態
我用過的唯一乙個狀態函式是eof(), 它返回是否標誌已經到了檔案末尾。 我主要用在迴圈中。 例如, 這個**斷統計小寫『e』 在檔案中出現的次數。
ifstream fin("file.txt");
char ch; int counter;
while (!fin.eof())
fin.close();
C 之輸入輸出檔案流
輸入檔案流與輸出檔案流的 功能實現 輸入檔案流 include include using namespace std int main ifs.open hello.txt ios in 使用open開啟,ios in可省略 if ifs ifstream ifs hello.txt 直接通過建構...
輸入輸出檔案的定位
對輸入流操作 seekg 與tellg 對輸出流操作 seekp 與tellp seekg 是對輸入檔案定位,它有兩個引數 第乙個引數是偏移量,第二個引數是基位址。ios beg 表示輸入流的開始位置 ios cur 表示輸入流的當前位置 ios end 表示輸入流的結束位置 ifstream in...
C 檔案輸入輸出
檔案輸入輸出 1 directory info 和file info 型別 directory和file通過靜態成員實現操作,擴充套件了system.object。返回強型別物件。directoryinfo和fileinfo通過例項級方法實現 必須使用new關鍵字分配它們 從filesystemin...