位置:首頁 > 高級語言 > C語言教學 > C語言文件讀寫I/O

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);

這兩個函數用來讀或寫存儲器塊 - 通常是數組或結構。