C 檔案讀寫

C 檔案讀寫

上一章我們講解了 C 語言處理的標準輸入和輸出裝置。本章我們將介紹 C 程式設計師如何建立、開啟、關閉文字檔案或二進位制檔案。

一個檔案,無論它是文字檔案還是二進位制檔案,都是代表了一系列的位元組。C 語言不僅提供了訪問頂層的函式,也提供了底層(OS)呼叫來處理儲存裝置上的檔案。本章將講解檔案管理的重要呼叫。

開啟檔案

您可以使用 fopen( ) 函式來建立一個新的檔案或者開啟一個已有的檔案,這個呼叫會初始化型別 FILE 的一個物件,型別 FILE 包含了所有用來控制流的必要的資訊。下面是這個函式呼叫的原型:

FILE *fopen( const char * filename, const char * mode );

在這裡,filename 是字串,用來命名檔案,訪問模式 mode 的值可以是下列值中的一個:

模式描述
r開啟一個已有的文字檔案,允許讀取檔案。
w開啟一個文字檔案,允許寫入檔案。如果檔案不存在,則會建立一個新檔案。在這裡,您的程式會從檔案的開頭寫入內容。如果檔案存在,則該會被截斷為零長度,重新寫入。
a開啟一個文字檔案,以追加模式寫入檔案。如果檔案不存在,則會建立一個新檔案。在這裡,您的程式會在已有的檔案內容中追加內容。
r+開啟一個文字檔案,允許讀寫檔案。
w+開啟一個文字檔案,允許讀寫檔案。如果檔案已存在,則檔案會被截斷為零長度,如果檔案不存在,則會建立一個新檔案。
a+開啟一個文字檔案,允許讀寫檔案。如果檔案不存在,則會建立一個新檔案。讀取會從檔案的開頭開始,寫入則只能是追加模式。

如果處理的是二進位制檔案,則需使用下面的訪問模式來取代上面的訪問模式:

"rb", "wb", "ab", "rb+", "r+b", "wb+", "w+b", "ab+", "a+b"

關閉檔案

為了關閉檔案,請使用 fclose( ) 函式。函式的原型如下:

 int fclose( FILE *fp );

如果成功關閉檔案,fclose( ) 函式返回零,如果關閉檔案時發生錯誤,函式返回 EOF。這個函式實際上,會清空緩衝區中的資料,關閉檔案,並釋放用於該檔案的所有記憶體。EOF 是一個定義在標頭檔案 stdio.h 中的常量。

C 標準庫提供了各種函式來按字元或者以固定長度字串的形式讀寫檔案。

寫入檔案

下面是把字元寫入到流中的最簡單的函式:

int fputc( int c, FILE *fp );

函式 fputc() 把引數 c 的字元值寫入到 fp 所指向的輸出流中。如果寫入成功,它會返回寫入的字元,如果發生錯誤,則會返回 EOF。您可以使用下面的函式來把一個以 null 結尾的字串寫入到流中:

int fputs( const char *s, FILE *fp );

函式 fputs() 把字串 s 寫入到 fp 所指向的輸出流中。如果寫入成功,它會返回一個非負值,如果發生錯誤,則會返回 EOF。您也可以使用 int fprintf(FILE *fp,const char *format, ...) 函式把一個字串寫入到檔案中。嘗試下面的例項:

注意:請確保您有可用的 tmp 目錄,如果不存在該目錄,則需要在您的計算機上先建立該目錄。

/tmp 一般是 Linux 系統上的臨時目錄,如果你在 Windows 系統上執行,則需要修改為本地環境中已存在的目錄,例如: C:\tmpD:\tmp等。

例項

#include <stdio.h> int main() { FILE *fp = NULL; fp = fopen("/tmp/test.txt", "w+"); fprintf(fp, "This is testing for fprintf...\n"); fputs("This is testing for fputs...\n", fp); fclose(fp); }

當上面的程式碼被編譯和執行時,它會在 /tmp 目錄中建立一個新的檔案 test.txt,並使用兩個不同的函式寫入兩行。接下來讓我們來讀取這個檔案。

讀取檔案

下面是從檔案讀取單個字元的最簡單的函式:

int fgetc( FILE * fp );

fgetc() 函式從 fp 所指向的輸入檔案中讀取一個字元。返回值是讀取的字元,如果發生錯誤則返回 EOF。下面的函式允許您從流中讀取一個字串:

char *fgets( char *buf, int n, FILE *fp );

函式 fgets() 從 fp 所指向的輸入流中讀取 n - 1 個字元。它會把讀取的字串複製到緩衝區 buf,並在最後追加一個 null 字元來終止字串。

如果這個函式在讀取最後一個字元之前就遇到一個換行符 '\n' 或檔案的末尾 EOF,則只會返回讀取到的字元,包括換行符。您也可以使用 int fscanf(FILE *fp, const char *format, ...) 函式來從檔案中讀取字串,但是在遇到第一個空格和換行符時,它會停止讀取。

例項

#include <stdio.h> int main() { FILE *fp = NULL; char buff[255]; fp = fopen("/tmp/test.txt", "r"); fscanf(fp, "%s", buff); printf("1: %s\n", buff ); fgets(buff, 255, (FILE*)fp); printf("2: %s\n", buff ); fgets(buff, 255, (FILE*)fp); printf("3: %s\n", buff ); fclose(fp); }

當上面的程式碼被編譯和執行時,它會讀取上一部分建立的檔案,產生下列結果:

1: This
2: is testing for fprintf...

3: This is testing for fputs...

首先,fscanf() 方法只讀取了 This,因為它在後邊遇到了一個空格。其次,呼叫 fgets() 讀取剩餘的部分,直到行尾。最後,呼叫 fgets() 完整地讀取第二行。

二進位制 I/O 函式

下面兩個函式用於二進位制輸入和輸出:

size_t fread(void *ptr, size_t size_of_elements, size_t number_of_elements, FILE *a_file); size_t fwrite(const void *ptr, size_t size_of_elements, size_t number_of_elements, FILE *a_file);

這兩個函式都是用於儲存塊的讀寫 - 通常是陣列或結構體。