C語言文件讀寫I/O
有關C語言編程處理標準輸入和輸出設備將在最後一章解釋。在本章我們將看到C程序員如何創建其數據存儲:打開,關閉文本文件或二進製文件。
文件代表了一個字節序列,如果它是一個文本文件或二進製文件也不要緊。 C語言編程語言提供了高層次的功能接入以及低級彆(OS級彆)調用來處理存儲設備和文件。本章將引導完成對文件管理的重要調用。
打開文件
可以使用 fopen()函數來創建一個新的文件或打開現有的文件,這個調用將初始化文件類型的對象,其中包含必要的控製流的所有信息。下麵是這個函數調用的原型:
FILE *fopen( const char * filename, const char * mode );
在這裡,文件名(filename)是字符串文字,用它來命名文件,訪問模式可以是以下值之一:
模式 | 描述 |
---|---|
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-如果有錯誤。可以使用下麵的函數寫一個空值終止字符串流:
int fputs( const char *s, FILE *fp );
函數fputs()寫入字符串s到由fp引用的輸出流。它在成功時返回一個非負值,否則返回EOF表示錯誤。可以使用fprintf(FILE *fp,const char *format, ...) 函數以及寫一個字符串到一個文件中。試試下麵的例子:
請確保有/tmp目錄可用,如果冇有則繼續之前,必須機器上創建這個目錄。
#include <stdio.h> main() { FILE *fp; fp = fopen("/tmp/test.txt", "w+"); fprintf(fp, "This is testing for fprintf... "); fputs("This is testing for fputs... ", 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)字符終止字符串。
如果該函數遇到換行符' '或文件EOF在結束之前,已經讀讀的最大字符數,則僅返回字符讀取到這一點,包括新行字符。也可以使用 int fscanf(FILE *fp, const char *format, ...) 函數從文件中讀取的字符串,但它讀取遇到第一個空格字符後停止。
#include <stdio.h> main() { FILE *fp; char buff[255]; fp = fopen("/tmp/test.txt", "r"); fscanf(fp, "%s", buff); printf("1 : %s ", buff ); fgets(buff, 255, (FILE*)fp); printf("2: %s ", buff ); fgets(buff, 255, (FILE*)fp); printf("3: %s ", buff ); fclose(fp); }
當上述代碼被編譯和執行時,它讀取在前麵的部分中創建的文件,並且產生以下結果:
1 : This 2: is testing for fprintf... 3: This is testing for fputs...
讓我們來看看更多的細節,看看這裡發生什麼。首先fscanf()方法讀取隻是因為這之後它遇到了一個空格,第二次調用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);
這兩個函數用來讀或寫存儲器塊 - 通常是數組或結構。