C語言 - 第三十六章 | 檔案 I/O - 未格式化檔案 I/O
未格式化檔案 I/O
處理檔案的輸出入,必須先include <stdio.h>
標頭,如果要處理檔案輸出,要使用fopen()
函式開啟檔案。
1 | FILE* fopen (const char*, const char*); |
FILE
是個struct
自訂型態。
1 | typedef struct _iobuf { |
fopen()
會傳回一個FILE
實例的位址值,實際上不太需要了解FILE
的每個成員作用,只要將FILE
的位址值傳給像是fgetc()
、fputc()
、fgets()
、fputs()
的函式,進行相對應的檔案I/O
處理即可。
fopen()
的第一個參數用來指定要開啟的檔案名稱,第二個參數用來指定檔案I/O
模式,模式基本上就是讀、寫、附加,分別可使用r
、w
與a
來設定,如果加上+
,表示檔案可讀可寫,如果加上b
,表示以區塊(block
)方式,也就是二進位方式進行讀寫,例如以下是可設定的模式。
參數 | 說明 |
---|---|
r | 開啟檔案進行唯讀,若檔案不存在,則傳回 NULL |
w | 開啟檔案進行唯寫,若檔案不存在,則建立新檔,若檔案存在則將之刪除,再建立新檔 |
a | 開啟檔案進行附加,若檔案存在,則資料從檔案尾端寫入,若檔案不存在則建立新檔 |
rb | 以二進位模式開啟檔案進行唯讀,Windows 下需要加 b,Linux 下則會予以忽略 |
wb | 以二進位模式開啟檔案進行唯寫,Windows 下需要加 b,Linux 下則會予以忽略 |
ab | 以二進位模式開啟檔案進行附加,Windows 下需要加 b,Linux 下則會予以忽略 |
r+ | 開啟檔案進行讀寫,若檔案不存在,則建立新檔,若檔案存在,資料將從檔案開頭進行覆寫 |
w+ | 開啟檔案進行讀寫,若檔案不存在,則建立新檔,若檔案存在則覆寫原有的資料 |
a+ | 開啟檔案進行附加、讀取,若檔案不存在則建立新檔,若檔案存在,則資料從檔案尾端寫入 |
r+b | 以二進位方式開啟檔案進行讀寫,Windows 下需要加 b,Linux 下則會予以忽略 |
w+b | 以二進位方式開啟檔案進行讀寫,Windows 下需要加 b,Linux 下則會予以忽略 |
a+b | 以二進位方式開啟檔案進行附加、讀取,Windows 下需要加 b,Linux 下則會予以忽略 |
註:
Windows
作業系統將文字檔和二進位檔案當作兩種不同的檔案,而Linux
則不區別,在Windows
下讀寫非文字檔案,必須加上b
模式,在Linux
下則會忽略b
。
此為開啟一個檔案進行讀取。
1 | FILE *file = fopen("test.txt", "w"); |
若開啟檔案成功,則file
將儲存位址值,可以使用以下的程式片段來測試檔案是否開啟成功。
1 | if(file == NULL) { |
NULL
為使用#define
定義的展開字,其值為0
。
1 |
fopen()
會使用緩衝區來減少對磁碟的實際I/O
,以加快檔案存取效率,在程式中進行讀寫動作時,實際上會先對緩衝區作存取,而非實際的磁碟,檔案開啟一個重要的觀念與習慣是,不使用檔案時,一定要記得關閉檔案,關閉檔案會將緩衝區中的資料真正寫入磁碟,若忘了關閉檔案,可能會造成資料的遺失。
可以使用fclose()
來關閉檔案。
1 | int fclose(FILE *fp); |
若檔案正常關閉,則傳回0
,否則將傳回非0
值。
開啟檔案之後,你可以使用fgetc()
來讀取檔案中的字元,使用fputc()
來將字元寫入檔案。
1 | int fgetc(FILE* fp); |
fgetc()
傳入FILE
實例的位址值,每執行一次就會從檔案中讀取一個字元,直到讀到檔尾(End of File, EOF
)為止,文字模式時判斷檔案結尾。
1 | while((ch = fgetc(file)) != EOF) { |
使用fgetc()
,只要指定FILE
位址值給它就可以了,而fputc()
則指定要寫入的字元及FILE
位址值。
下面這個程式直接示範如何讀取並寫入純文字檔案,會將指定的檔案讀取並複製至另一個檔案。
1 |
|
也可以使用fgets()
來讀取整個字串,使用fputs()
來寫入整個字串。
1 | char* fgets(char *str, int length, FILE *fp); |
fgets()
第一個參數為要讀入的字串儲存的陣列位址,第二個參數為要讀入的字元長度,由於字串必須包留字元陣列最後一個元素為空白字元,才視之為字串,所以實際讀入的長度為length - 1
,第三個參數為FILE
位址值,而fputs()
第一個參數為寫入的字串,第二個參數為 FILE
位址值。
以下的程式使用fgets()
、fputs()
改寫上面這個程式。
1 |
|
在程式執行過程開啟的標準輸出stdout
、標準輸入stdin
、標準錯誤stderr
,事實上也是檔案串流的特例,在C
中,也常見到以下的方式,以便直接控制這三個標準輸入、輸出、錯誤。
1 |
|
註:以上參考了
未格式化檔案 I/O