在C語言中,有關文件操作的函數多達數十種,但並非每個函數都經常會被用到。
本文對實際軟件開發項目中常用的C文件操作函數的用法進行了總結,並用實際的C代碼來演示了它們的用法。
1. C語言中常用的文件操作函數總結
(1) fopen
作用:打開文件。
表頭文件:#include <stdio.h>
定義函數:FILE *fopen(const char *path, const char *mode);
函數說明:參數path字符串包含欲打開的文件路徑及文件名,參數mode字符串則代表著流形態。
mode有下列幾種形態字符串:
r:打開只讀文件,該文件必須存在。
r+:打開可讀寫的文件,該文件必須存在。
w:打開只寫文件,若文件存在則文件長度清為0,即該文件內容會消失。若文件不存在則建立該文件。
w+:打開可讀寫文件,若文件存在則文件長度清為零,即該文件內容會消失。若文件不存在則建立該文件。
a:以附加的方式打開只寫文件。若文件不存在,則會建立該文件,如果文件存在,寫入的數據會被加到文件尾,即文件原先的內容會被保留。
a+:以附加方式打開可讀寫的文件。若文件不存在,則會建立該文件,如果文件存在,寫入的數據會被加到文件尾後,即文件原先的內容會被保留。
上述的形態字符串都可以再加一個b字符,如rb、w+b或ab+等組合,加入b字符用來告訴函數庫打開的文件為二進制文件,而非純文字文件。不過在POSIX系統,包含Linux都會忽略該字符。由fopen()所建立的新文件會具有S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH(0666)權限,此文件權限也會參考umask值。
返回值:文件順利打開後,指向該流的文件指針就會被返回。如果文件打開失敗,則返回NULL,並把錯誤代碼存在errno中。
附加說明:一般而言,打開文件後會作一些文件讀取或寫入的動作,若打開文件失敗,接下來的讀寫動作也無法順利進行,所以在fopen()後請作錯誤判斷及處理。
(2) fclose
作用:關閉文件
表頭文件:#include <stdio.h>
定義函數:int fclose(FILE *stream);
函數說明:fclose()用來關閉先前fopen()打開的文件。此動作會讓緩沖區內的數據寫入文件中,並釋放系統所提供的文件資源。
返回值:若關閉文件動作成功則返回0,有錯誤發生時則返回EOF並把錯誤代碼存到errno中。
錯誤代碼:EBADF表示參數stream非已打開的文件。
(3) fgetc
作用:由文件中讀取一個字符。
表頭文件:include <stdio.h>
定義函數:int fgetc(FILE *stream);
函數說明:fgetc()從參數stream所指的文件中讀取一個字符。若讀到文件尾而無數據時便返回EOF。
返回值:getc()會返回讀取到的字符,若返回EOF則表示到了文件尾。
(4) fgets
作用:由文件中讀取一字符串。
表頭文件:include<stdio.h>
定義函數:char *fgets(char *s, int size, FILE *stream);
函數說明:fgets()用來從參數stream所指的文件內讀入字符並存到參數s所指的內存空間,直到出現換行字符、讀到文件尾或是已讀了size-1個字符為止,最後會加上NULL作為字符串結束。
返回值:fgets()若成功則返回s指針,返回NULL則表示有錯誤發生。
(5) fflush
作用:更新緩沖區。
表頭文件:#include <stdio.h>
定義函數:int fflush(FILE *stream);
函數說明:fflush()會強迫將緩沖區內的數據寫回參數stream指定的文件中。如果參數stream為NULL,fflush()會將所有打開的文件數據更新。
返回值:成功返回0,失敗返回EOF,錯誤代碼存於errno中。
錯誤代碼:EBADF參數stream指定的文件未被打開,或打開狀態為只讀。
(6) fputc
作用:將一指定字符寫入文件流中。
表頭文件:#include <stdio.h>
定義函數:int fputc(int c, FILE *stream);
函數說明:fputc會將參數c轉為unsigned char後寫入參數stream指定的文件中。
返回值:fputc()會返回寫入成功的字符,即參數c。若返回EOF,則代表寫入失敗。
(7) fputs
作用:將一指定的字符串寫入文件內。
表頭文件:#include <stdio.h>
定義函數:int fputs(const char *s, FILE *stream);
函數說明:fputs()用來將參數s所指的字符串寫入到參數stream所指的文件內。
返回值:若成功,則返回寫入的字符個數,返回EOF則表示有錯誤發生。
(8) fread
作用:從文件流讀取數據。
表頭文件:#include <stdio.h>
定義函數:size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
函數說明:fread()用來從文件流中讀取數據。參數stream為已打開的文件指針,參數ptr指向欲存放讀取進來的數據空間,讀取的字符數以參數size*nmemb來決定。fread()會返回實際讀取到的nmemb數目,如果此值比參數nmemb來得小,則代表可能讀到了文件尾或有錯誤發生,這時必須用feof()或ferror()來決定發生了什麼情況。
返回值:返回實際讀取到的nmemb數目。
(9) fseek
作用:移動文件流的讀寫位置。
表頭文件:#include <stdio.h>
定義函數:int fseek(FILE *stream, long offset, int whence);
函數說明:fseek()用來移動文件流的讀寫位置。參數stream為已打開的文件指針,參數offset為根據參數whence來移動讀寫位置的位移數。
參數whence為下列其中一種:
SEEK_SET:從距文件開頭offset位移量為新的讀寫位置,SEEK_CUR以目前的讀寫位置往後增加offset個位移量,SEEK_END將讀寫位置指向文件尾後再增加offset個位移量。
當whence值為SEEK_CUR 或SEEK_END時,參數offset允許負值的出現。
下列是較特別的使用方式:
1) 欲將讀寫位置移動到文件頭時:fseek(FILE *stream, 0, SEEK_SET);
2) 欲將讀寫位置移動到文件尾時:fseek(FILE *stream, 0, SEEK_END);
返回值:當調用成功時,則返回0,若有錯誤,則返回-1,errno會存放錯誤代碼。
附加說明:fseek()不像lseek()會返回讀寫位置,因此必須使用ftell()來取得目前讀寫的位置。
(10) ftell
作用:取得文件流的讀取位置。
表頭文件:#include <stdio.h>
定義函數:long ftell(FILE * stream);
函數說明:ftell()用來取得文件流目前的讀寫位置,參數stream為已打開的文件指針。
返回值:當調用成功時則返回目前的讀寫位置,若有錯誤則返回-1,errno會存放錯誤代碼。
錯誤代碼:EBADF 參數stream無效或可移動讀寫位置的文件流。
(11) fwrite
作用:將數據寫至文件流。
表頭文件:#include <stdio.h>
定義函數:size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
函數說明:fwrite()用來將數據寫入文件流中。參數stream為已打開的文件指針,參數ptr指向欲寫入的數據地址,總共寫入的字符數以參數size*nmemb來決定。fwrite()會返回實際寫入的nmemb數目。
返回值:返回實際寫入的nmemb數目。
(12) getc
作用:由文件中讀取一個字符。
表頭文件:#include <stdio.h>
定義函數:int getc(FILE *stream);
函數說明:getc()用來從參數stream所指的文件中讀取一個字符。若讀到文件尾而無數據時,便返回EOF。雖然getc()與fgetc()作用相同,但getc()為宏定義,非真正的函數調用。
返回值:getc()會返回讀取到的字符,若返回EOF則表示到了文件尾。
(13) getchar
作用:由標准輸入設備內讀進一字符。
表頭文件:#include <stdio.h>
定義函數:int getchar(void);
函數說明:getchar()用來從標准輸入設備中讀取一個字符,然後將該字符從unsigned char轉換成int後返回。
返回值:getchar()會返回讀取到的字符,若返回EOF則表示有錯誤發生。
附加說明:getchar()非真正函數,而是getc(stdin)宏定義。
(14) gets
作用:由標准輸入設備內讀進一字符串。
表頭文件:#include <stdio.h>
定義函數:char *gets(char *s);
函數說明:gets()用來從標准設備讀入字符並存到參數s所指的內存空間,直到出現換行字符或讀到文件尾為止,最後加上NULL作為字符串結束。
返回值:gets()若成功則返回s指針,返回NULL則表示有錯誤發生。
附加說明:由於gets()無法知道字符串s的大小,必須遇到換行字符或文件尾才會結束輸入,因此容易造成緩沖溢出的安全性問題。建議使用fgets()取代。
(15) putc
作用:將一指定字符寫入文件中。
表頭文件:#include <stdio.h>
定義函數:int putc(int c, FILE *stream);
函數說明:putc()會將參數c轉為unsigned char後寫入參數stream指定的文件中。雖然putc()與fputc()作用相同,但putc()為宏定義,非真正的函數調用。
返回值:putc()會返回寫入成功的字符,即參數c。若返回EOF則代表寫入失敗。
(16) putchar
作用:將指定的字符寫到標准輸出設備。
表頭文件:#include <stdio.h>
定義函數:int putchar(int c);
函數說明:putchar()用來將參數c字符寫到標准輸出設備。
返回值:putchar()會返回輸出成功的字符,即參數c。若返回EOF,則代表輸出失敗。
附加說明:putchar()非真正函數,而是putc(c, stdout)宏定義。
(17) feof
作用:檢查文件流是否讀到了文件尾。
表頭文件:#include <stdio.h>
定義函數:int feof(FILE * stream);
函數說明:feof()用來偵測是否讀取到了文件尾,尾數stream為fopen()所返回之文件指針。如果已到文件尾,則返回非零值,其他情況返回0。
返回值:返回非零值代表已到達文件尾。
(18) clearer
作用:清除文件流的錯誤旗標。
表頭文件:#include <stdio.h>
定義函數:void clearerr(FILE *stream);
函數說明:clearerr()清除參數stream指定的文件流所使用的錯誤旗標。
返回值:無。
2. C語言中常用的文件操作函數的使用方法演示
假設在當前工程目錄下有一個有具體內容的文件Example.txt,則利用文件操作函數對其進行各種操作的演示如下代碼所示(注意:如果要測試某一個或幾個函數,只需要提取其中的部分代碼即可):
*修改記錄1://修改歷史記錄,包括修改日期、版本號、修改人及修改內容 *修改日期: 20140503 *版本號: V1.0 *修改人: Zhou Zhaoxiong *修改內容:創建 **********************************************************************/ #include <stdio.h> #include <stdlib.h> #include <string.h> // 數據類型 typedef unsigned char UINT8; typedef unsigned int UINT32; /********************************************************************** *功能描述:主函數 *輸入參數:無 *輸出參數:無 *返回值:0-執行成功 1-執行失敗 *其它說明:無 *修改日期 版本號 修改人 修改內容 * ---------------------------------------------------------------------------------------------- *20140503 V1.0 Zhou Zhaoxiong 創建 ***********************************************************************/ UINT32 main(void) { FILE *fp = NULL; UINT8 cSingleChar = '\0'; UINT8 szString[100] = {0}; UINT32 iFileDescription = 0; UINT8 szAlphabeticSet[30] = {0}; UINT32 iLoopFlg = 0; UINT32 iCharCount = 0; UINT8 *pIdentify = NULL; // fopen fp = fopen("Example.txt", "r"); // 在當前工程目錄下有一個有具體內容的文件Example.txt if (fp == NULL) { printf("Open the file failed!\n"); return 1; } // fgetc if ((cSingleChar = fgetc(fp)) != EOF) { printf("%c\n", cSingleChar); fclose(fp); // 只讀取第一個字符 } else { printf("The file is empty!\n"); fclose(fp); } // fgets //