feof是C語言標準庫函式,其原型在stdio.h中,其功能是檢測流上的檔案結束符,如果檔案結束,則返回非0值,否則返回0(即,檔案結束:返回非0值,檔案未結束,返回0值),檔案結束符只能被clearerr()清除。(這裡的檢測流上的檔案結束符就相當於音效卡檢測電流信號的一個過程)
基本介紹
- 中文名:feof()
- 類型:c語言函式
- 功 能:檢測流上的檔案結束符
- 原 型:int feof(FILE *stream);
函式名,功 能,用 法,程式例,
函式名
feof
功 能
檢測流上的檔案結束符
The function feof() tests the end-of-file indicator for the stream
pointed to by stream, returning non-zero if it is set. The end-of-file
indicator can only be cleared by the functionclearerr().
如果檔案結束,則返回非0值,否則返回0,檔案結束符只能被clearerr()清除。
用 法
int feof(FILE *stream);
參數
流 :FILE結構的指針
注意:feof判斷檔案結束是通過讀取函式fread/fscanf等返回錯誤來識別的,故而判斷檔案是否結束應該是在讀取函式之後進行判斷。比如,在while循環讀取一個檔案時,如果是在讀取函式之前進行判斷,則如果檔案最後一行是空白行,可能會造成記憶體錯誤。
程式例
#include<stdio.h>int main(void){ FILE *stream; /*open a file for reading*/ stream = fopen("DUMMY.FIL", "r"); /*read a character from the file*/ fgetc(stream); /*check for EOF*/ if(feof(stream)) printf("We have reached the end of file\n"); /*close the file*/ fclose(stream); return 0;}
feof(fp)有兩個返回值:如果遇到檔案結束,函式feof(fp)的值為非零值,否則為0。
EOF是文本檔案結束的標誌。在文本檔案中,數據是以字元的ASCⅡ代碼值的形式存放,普通字元的ASCⅡ代碼的範圍是32到127(十進制),EOF的16進制代碼為0xFF(十進制為-1),因此可以用EOF作為檔案結束標誌。
當把數據以二進制形式存放到檔案中時,就會有-1值的出現,因此不能採用EOF作為二進制檔案的結束標誌。為解決這一個問題,ASCI C提供一個feof函式,用來判斷檔案是否結束。feof函式既可用以判斷二進制檔案又可用以判斷文本檔案。
“C”語言的“feof()”函式和資料庫中“eof()”函式的運作是完全不同的。資料庫中“eof()”函式讀取當前指針的位置,“C”語言的“feof()”函式返回的是最後一次“讀操作的內容”。多年來把“位置和內容”相混,從而造成了對這一概念的似是而非。
那么,位置和內容到底有何不同呢?舉個簡單的例子,比如有人說“你走到火車的最後一節車箱”這就是位置。而如果說“請你一直向後走,摸到鐵軌結束”這就是內容。也就是說用內容來判斷會“多走一節”。這就是完全依賴於“while(!feof(FP)){...}”進行檔案複製時,目標文檔總會比源文檔“多出一些”的原因。
在“C”檔案讀取操作時不能完全依賴於“while(!feof(FP)){...}”的判斷。下面代碼是改進後的代碼,該代碼執行後output檔案內容和input檔案內容一致,與使用“while(!feof(FP)){...}”相比,output檔案的結尾符號(EOF)沒有被讀入到input檔案中。
//main.c linux 下編譯通過、vc下也行。
#include <stdlib.h>#include <stdio.h>int main(void){ FILE *in, *out; int ch; if ((in = fopen("./output.txt", "r"))== NULL) //input.txt must exist in current directory. { fprintf(stderr, "Cannot open inputfile\n"); exit(0); } if((out=fopen("./input.txt","w"))==NULL) { fprintf(stderr,"Can not open the file.\n"); exit(0); } while(1) { ch=fgetc(in); if(ch == -1) break; fprintf(stdout,"The ASC of char %c is %d\n ",ch,ch); fputc(ch,out); } fclose(in); fclose(out); return 0;}
與EOF的區別
在stdio.h中可以看到如下定義:
#define EOF (-1)#define _IOEOF 0x0010#define feof(_stream) ((_stream)->_flag & _IOEOF)int c;while(!feof(fp)){ c = fgetc(fp); printf("%X\n", c);}
會發現多輸出了一個FF,原因就是在讀完最後一個字元後,fp->flag仍然沒有被置為_IOEOF,因而feof()仍然沒有探測到檔案結尾。直到再次調用fgetc()執行讀操作,feof()才能探測到檔案結尾。這樣就多輸出了一個-1(即FF)。
正確的寫法應該是:
int c;c = fgetc(fp);while(!feof(fp)){ printf("%X\n", c); c = fgetc(fp);//最後一個c的值為-1,但是無妨,因為其他所有的循環操作都要放在此句話上面}
feof()可以用EOF代替嗎?不可以。fgetc返回-1時,有兩種情況:讀到檔案結尾或是讀取錯誤。因此我們無法確信檔案已經結束, 因為可能是讀取錯誤! 這時我們需要feof()。