C語言文件函數
1.說明:
t(text): 文本文件,可省略不寫
b(banary): 二進制文件
+: 讀和寫
name:要打開的文件的(路徑)名字
mode:要打開的文件的模式
FILE:文件指針(結構體)
打開方式mode說明:
r :以只讀方式打開文件,只允許讀取,不允許寫入。該文件必須存在
r+ :以讀/寫方式打開文件,允許讀取和寫入。該文件必須存在
rb+:以讀/寫方式打開一個二進制文件,允許讀/寫數據,文件必須存在
rt+:以讀/寫方式打開一個文本文件,允許讀和寫,文件必須存在
w :以只寫方式打開文件,若文件存在則長度清爲0,即該文件內容消失,若不存在則創建該文件
w+ :以讀/寫方式打開文件,若文件存在則文件長度清爲零,即該文件內容會消失。若文件不存在則建立該文件
a :追加的方式打開只寫文件。若文件不存在,建立該文件,否則寫入的數據會被加到文件尾(EOF保留)
a+ :以追加方式打開可讀/寫的文件;
wb :以只寫方式打開或新建一個二進制文件,只允許寫數據
wb+:以讀/寫方式打開或建立一個二進制文件,允許讀和寫
wt+:以讀/寫方式打開或建立一個文本文件,允許讀寫
at+:以讀/寫方式打開一個文本文件,允許讀或在文本末追加數據
ab+:以讀/寫方式打開一個二進制文件,允許讀或在文件末追加數據
2.fopen函數
- 原型:
FILE *fopen(char const *name, char const *mode)
- 返回:打開成功返回指向FILE結構的指針,否則返回NULL
- 注意:應該始終檢查fopen的返回值!如果失敗返回NULL,不檢查則會把NULL指針傳給後續的I/O函數
- 同類型函數:freopen函數
1.原型:
FILE *freopen(char const *filename, char const *mode, FILE *stream)
2.作用:打開或者重新打開一個特定的文件流
3.函數先試圖關閉要打開的文件流(有可能是以前的,也有可能是標準流的stdin、stdout、stderr),然後用指定的文件和模式打開這個流
4.如果成功返回第三個參數值,否則返回NULL - 示例:
FILE *input;
input = fopen("data3", "r");
if(input == NULL) //檢查打開是否成功
{
perror("data3"); //返回錯誤的方式
exit(EXIT_FAILURE); //終止程序的執行
}
- 注:如果錯誤返回:
data3:No such file or directory
3.flcose函數
- 原型:
int fclose(FILE *f)
- 返回:成功返回零值,否則返回EOF並把錯誤代碼存到errno
- 示例:
int main(int ac, char **av)
{
int exit_status = EXIT_SUCCESS;
FILE *input;
/*當還有更多的文件名時*/
while(*++av != NULL)
{
/*試圖打開這個文件*/
input = fopen(*av, "r");
if(input == NULL)
{
perror(*av);
exit_status = EXIT_FAILURE;
continue;
}
/*處理文件*/
/*關閉文件*/
if(fclose(input) != 0)
{
perror("fclose");
exit(EXIT_FAILURE);
}
}
return exit_status;
}
- **注:**fclose會在文件關閉之前刷新緩衝區。程序一定要檢查文件是否關閉,因爲很可能在fclose調用之前文件就已經關閉。
4.fgetc與getchar函數
- 原型:
int fgetc(FILE *stream)
int getchar(void)
- 返回:返回整形值是爲了允許函數報告文件的末尾(EOF)
- 注意:
1.fgetc需要操作的流是要參數傳遞,getchar需要從標準輸入讀取並把它作爲返回值返回
2.getchar函數是fgetc的宏定義
5.fputc與putchar函數
- 原型:
int fputc(int character, FILE *stream)
int putchar(int character)
- 說明:第一個參數是要被打印的字符
- 注意:
1.打印之前,函數把第一個整形參數裁剪爲一個無符號字符型值
2.putchar函數是fputc的宏定義
如果任何原因導致函數失敗,都返回EOF
void main(int argc, char *argv[])
{
char ch = '\0';
FILE *file = NULL;
if(argc != 2)
{
printf("Error format,Usage: display filename1\n");
return;
}
if((file = fopen(argv[1], "r")) == NULL)
{
printf("The file <%s> can not be opened.\n", argv[1]);
return;
}
while((ch = fgetc(file)) != EOF)
{
putchar(ch);
}
fclose(file);
}
putchar('abc')
- 上述函數只打印一個字符,打印哪個,根據編譯器選擇
- fgetc和fputc都是真正的函數,但getchar和putchar都是通過#define指令定義的宏,宏在執行效率上稍高
6.fprintf函數:
- 函數原型:
int fprintf(FILE *stream, char *format[, argument,...])
- 功能:傳送格式化輸出到一個文件中
- 參數說明:FILE*一個FILE型的指針;char*格式化輸入函數,和printf裏的格式一樣
返回值:成功時返回轉換的字節數,失敗時返回一個負數
eg:
fprintf(fp,"%s\n",str)
7.fscanf函數:
- 函數原型:
int fscanf(FILE *stream, char *format[,argument...])
- 功能:從一個流中執行格式化輸入
- 參數說明:FILE*一個FILE型的指針;char*格式化輸出函數,和scanf裏的格式一樣
返回值:成功時返回轉換的字節數,失敗時返回一個負數
eg:
fscanf(fp,"%s",str)
8.feof函數:
- 函數原型:int feof(FILE * stream)
- 作用:檢查文件流是否讀到了文件尾(在打印的同時會打印最後一個EOF)
- 返回值:非零值代表已到達文件尾,其他情況返回0
9.fgets函數與fputs函數:
- 函數原型:
char * fgets(char * s,int size,FILE * stream)
int fputs(const char * s,FILE * stream)
- 函數說明:
1.fgets:文件內讀入字符並存到參數s所指的內存空間,直到出現換行字符、讀到文件尾或是已讀了size-1個字符爲止,最後會加上NULL作爲字符串結束
2.fputs:將參數s所指的字符串寫入到參數stream所指的文件內 - 返回參數說明:
1.fgets:成功則返回s指針,返回NULL則表示有錯誤發生
2.fputs:成功則返回寫出的字符個數,返回EOF則表示有錯誤發生
10.fread函數:
- 函數原型:
size_t fread(void * ptr, size_t size, size_t count, FILE * stream)
- 參數說明:stream爲已打開的文件指針;ptr 指向欲存放讀取進來的數據空間(一個或多個值的數組);size是緩衝區每個元素的字節數;讀取的字符數以參數size*count來決定
- 返回參數說明:返回實際讀取到的count數目(不是字節數),如果此值比參數count 來得小,則代表可能讀到了文件尾或有錯誤發生,這時必須用feof()或ferror()來決定發生什麼事情
11.fwrite函數:
- 函數原型:
size_t fwrite(const void * ptr, size_t size, size_t count, FILE * stream)
- 參數說明:stream爲已打開的文件指針,參數ptr 指向欲寫入的數據地址,總共寫入的字符數以參數size*count來決定
- 返回值說明:返回實際寫入的count數目
/*從輸入文件讀取二進制數據並且把結果寫入到一個輸出文件*/
struct VALUE
{
long a;
float b;
char c[SIZE];
}value[ARRAY_SIZE];
...
n_value = fread(value, sizeof(struct VALUE), ARRAY_SIZE, input_stream);
fwrite(values, sizeof(struct VALUE), n_value, output_stream);
12.fseek函數:
- 函數原型:
int fseek(FILE * stream,long offset,int whence)
- 相似函數:
原型:
fsetpos(FILE *stream, fpos_t const *position)
作用:把文件位置設置爲存儲在這個位置(fpos_t指針)的值 - 函數說明:用來移動文件流的讀寫位置
參數說明:
1.stream爲已打開的文件指針,參數offset爲根據參數whence來移動讀寫位置的位移數
2.whence類型:SEEK_SET:從距文件開頭offset位移量爲新的讀寫位置(offset必須爲非負值);
SEEK_CUR:以目前的讀寫位置往後增加offset個位移量(offset可正可負);
SEEK_END:將讀寫位置指向文件尾後再增加offset個位移量(offset可正可負,如果爲正值將定位到文件尾的後面)(二進制流中可能不被支持,應該避免)備註:當whence值爲SEEK_CUR 或SEEK_END時,參數offset允許負值的出現
常用方式:
1.欲將讀寫位置移動到文件開頭時:fseek(FILE *stream,0,SEEK_SET);
2.欲將讀寫位置移動到文件尾時:fseek(FILE *stream,0,SEEK_END);返回參數說明:成功時則返回0,若有錯誤則返回-1
- 附加說明:fseek()不像lseek()會返回讀寫位置,因此必須使用ftell()來取得目前讀寫的位置
13.ftell函數:
- 函數原型:
long ftell(FILE * stream)
- 作用:取得文件流的讀取位置(下一個讀取或寫入將要開始的位置距離文件起始位置的偏移量)
- 返回參數說明:當調用成功時則返回目前的讀寫位置,若有錯誤則返回-1
14.fflush函數:
- 函數原型:
int fflush(FILE* stream)
- 函數說明:強制將緩衝區內的數據寫回參數stream指定的文件中
- 返回值說明:成功返回0,失敗返回EOF
#define putchar(ch) fputc(ch, stdout)
int main(int argc, char *argv[])
{
//char *buffer = (char *)malloc(20);
//char *buffer = "hello world!";
int datas[4] = {5, 6, 7, 8};
FILE *file = NULL;
int i = 0;
if((file = fopen(argv[1], "r")) == NULL)
{
printf("Open file error!\n");
return 0;
}
//fwrite(datas, sizeof(int), sizeof(datas) / sizeof(int), file);
fseek(file, sizeof(datas) + 1, SEEK_SET);
fread(datas, sizeof(int), sizeof(datas) / sizeof(int), file);
for(i = 0 ; i < sizeof(datas) / sizeof(int); ++i)
{
printf("%4d", datas[i]);
}
putchar(10);
fseek(file, 0, SEEK_SET);
fread(datas, sizeof(int), sizeof(datas) / sizeof(int), file);
for(i = 0 ; i < sizeof(datas) / sizeof(int); ++i)
{
printf("%4d", datas[i]);
}
putchar(10);
/*while((ch = getchar()) != '$')
{
fputc(ch, file);
}*/
/*if(EOF == fputs(buffer, file))
{
printf("Write file error!\n");
return 0;
}*/
//printf("%s\n", buffer);
/*while((ch = fgetc(file)) != EOF)
{
putchar(ch);
}*/
/*while(!feof(file))
{
putchar(fgetc(file));
}*/
fclose(file);
//free(buffer);
return 0;
}
15.clearerr函數:
- 函數原型:
void clearerr(FILE * stream)
- 作用:清除文件流的錯誤旗標
16.rewind函數(重設文件流的讀寫位置爲文件開頭):
- 函數原型:
void rewind(FILE * stream)
- 函數說明:把文件流的讀寫位置移至文件開頭
- 備註:此函數相當於調用
fseek(stream, 0, SEEK_SET)
- 相似函數:
原型:
fgetpos(FILE *stream, fpos_t, *position)
作用:在這個位置(fpos_t指針)存儲文件的當前位置
17.setbuf函數(設置文件流的緩衝區):
- 函數原型:
void setbuf(FILE * stream,char * buf)
- 函數說明:在打開文件流後,讀取內容之前,調用setbuf()可以用來設置文件流的緩衝區(防止I/O函數動態爲它分配一個緩衝區)
- 參數說明:參數stream爲指定的文件流,參數buf指向自定的緩衝區起始地址;如果參數buf爲NULL指針,則爲無緩衝I/O
- 注意:setbuf設置了另一個數組用於對流進行緩衝,數組的字符長度必須爲BUFSIZ(在stdio.h中定義)
18.setvbuf函數(設置文件流的緩衝區):
- 函數原型:
int setbuffer(FILE * stream, char * buf, int mode, size_t size)
- 函數說明:在打開文件流後,讀取內容之前,調用setvbuf()可用來設置文件流的緩衝區
- 參數說明:stream爲指定的文件流,參數buf指向自定的緩衝區起始地址,參數size爲緩衝區大小,mode用於指定緩衝的類型(
_IOFBF指定一個完全緩衝的流
_IONBF指定一個不緩衝的流
_IOLBF指定一個行緩衝流
) - 注意:最好用一個長度爲BUFSIZ(儘量爲系統內部使用的緩衝區的整數倍)的字符數組作爲緩衝區
19.tmpfile函數:
- 原型:
FILE *tmpfile(void)
- 作用:創建一個臨時文件保存數據(當文件關閉或程序終止自動刪除)
- 說明:如果文件必須以其他模式打開或者由一個程序打開另一個程序讀取則不能使用此函數,而是使用fopen函數:
- 注:臨時文件的名字創建:
原型:
char *tmpnam(char *name)
說明:如果參數爲NULL則返回一個指向靜態數組的指針,該數組包含了被創建的文件名(調用次數不超過TMP_MAX次,便沒有重名),否則參數便假定是一個指向長度至少爲L_tmpnam的字符數組的指針,且返回值爲這個參數
20.參考文章:
- 《C數組與指針》