未格式化檔案 I/O


在C++中要 開啟一個檔案,就是將它連結至一個串流,串流有三種型態:輸入串流(istream)、輸出串流(ostream)與輸入/輸出串流(iotream), 而與檔案處理相關的ifstream、ofstream及fstream則繼承這三個串流而來,它們的關係如下:
ios
|
--istream --|
|           ---ifstream--|
|                        |
|                        |---iostream--|
--ostream --|            |             ---fstream
            ---ofstream--|

要處理檔案的輸出入,您必須先include <fstream>標頭,如果要處理檔案輸入,您要宣告一個ifstream物件,要處理檔案輸出,您要宣告一個ofstream物件,要處 理檔案的輸出入,您要宣告一個fstream物件,建立串流物件之後,可以使用open()函式來連結串流,open()函式的雛型宣告如下:
void ifstream::open(const char *filename, openmode mode=ios::in);
void ofstream::open(const char *filename, openmode mode=ios::out | ios::trunc);
void fstream::open(const char *filename, openmode mode=ios::in | ios::out);


filename是檔案名稱,而mode決定檔案的開啟模式,它是由ios類別所定義的常數來決定,下面列出openmode的值與用途:
ios::in 檔案open為輸入模式(istream default)
ios::out 檔案open為寫入(ostream default)
ios::ate 從檔案尾端輸入輸出
ios::app 在檔案尾端以append模式寫入
ios::trunc 如果檔案存在,則清除檔案內容
ios::binary 以二進位模式open檔案

以二進位模式開啟檔案,與文字模式開啟檔案的不同在於,文字模式會發生字元轉換,而二進位模式不會,例如int數字9,在文字模式下會被轉換為編碼57,而二進位模式下則直接寫入int資料。

如果您使用ofstream來開啟檔案,若指定的檔案原先存在,則檔案會被清空,您可以使用附加方式,或是使用ifstream並指定ios::in與ios::out,即可保留原檔案的內容。

可以使用下面這個片段來開啟一個檔案:
ifstream fin;
fin.open("filename");


如果開啟失敗則串流會傳回false,您可以使用下面的片段來判斷:
if(!fin) {
    cout << "無法讀取檔案\n";
    // 其它處理
}

最低階的輸出與輸出函式為get()和put()函式,它們被重載(overload)多次,我們這邊介紹最基本的字元輸入與輸出,它們的函式雛型如下:
istream &get(char &ch);
ostream &put(char);

當讀取至檔尾時,get()函式會傳回false,也可以使用eof()函式來判斷是否讀取至檔案尾端;下面這個程式示範如何讀入一個文字檔案,並顯示在主控台上:
#include <iostream> 
#include <fstream>
using namespace std;

int main(int argc, char* argv[]) {
    char ch;

    if(argc != 2) {
        cout << "指令: read <檔案名稱>" << endl;
        return 1;
    }
                       
    ifstream fin;
fin.open(argv[1]);                      
                           
    if(!fin) {
        cout << "檔案I/O失敗" << endl;
        return 1;
    }
                                           
    while(!fin.eof()) {
        fin.get(ch);
        cout << ch;
    }
         
    fin.close();
                             
    return 0;
}

在開啟串流之後,最後記得使用close()函式將串流關閉;編譯時我們設定輸出檔案為read,以下為執行結果:
read test1.cpp
#include <iostream>
#include <fstream>
using namespace std;

int main(int argc, char* argv[]) {
    char ch;

    if(argc != 2) {
        cout << "指令: read <檔案名稱>\n";
        return 1;
    }

略 .... 

下面這個程式示範讀取使用者輸入,並將之寫入至檔案中:
#include <iostream> 
#include <fstream>
using namespace std;

int main(int argc, char* argv[]) {
char ch;

if(argc != 2) {
cout << "指令: write <filename>" << endl;
return 1;
}

ofstream fout(argv[1]);

if(!fout) {
cout << "檔案I/O失敗" << endl;
return 1;
}

cout << "輸入文字,以 'q' 字元結束" << endl;

do {
cin.get(ch);
fout.put(ch);
} while(ch != 'q');

fout.close();

return 0;
}

編譯時設定輸出檔案為write,以下是執行結果示範:
write test.txt
輸入文字,以 'q' 字元結束
這是一個測試
輸入的文字將輸入至檔案中
q

程式結束後,開啟test.txt,當中會有您所輸入的資料。