函式名
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循環讀取一個檔案時,如果是在讀取函式之前進行判斷,則如果檔案最後一行是空白行,可能會造成記憶體錯誤。
程式例
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下也行。
與EOF的區別
在stdio.h中可以看到如下定義:
會發現多輸出了一個FF,原因就是在讀完最後一個字元後,fp->flag仍然沒有被置為_IOEOF,因而feof()仍然沒有探測到檔案結尾。直到再次調用fgetc()執行讀操作,feof()才能探測到檔案結尾。這樣就多輸出了一個-1(即FF)。
正確的寫法應該是:
feof()可以用EOF代替嗎?不可以。fgetc返回-1時,有兩種情況:讀到檔案結尾或是讀取錯誤。因此我們無法確信檔案已經結束, 因為可能是讀取錯誤! 這時我們需要feof()。