feof (函式名)

2puT發表於2016-07-15

c語言函式
中文名
Fenton
類    型
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);

程式例

編輯
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include<stdio.h>
int main(void)
{
    FILE *stream;
    /*openafileforreading*/
    stream = fopen("DUMMY.FIL""r");
    /*readacharacterfromthefile*/
    fgetc(stream);
    /*checkforEOF*/
    if(feof(stream))
        printf("We have reached the end of file\n");
    /*closethefile*/
    fclose(stream);
    return 0;
}
feof(fp)有兩個返回值:如果遇到檔案結束,函式feof(fp)的值為非零值,否則為0。
EOF是文字檔案結束的標誌。在文字檔案中,資料是以字元的ASCⅡ程式碼值的形式存放,普通字元的ASCⅡ程式碼的範圍是32到127(十進位制),EOF的16進位制程式碼為0xFF(十進位制為-1),因此可以用EOF作為檔案結束標誌。[1] 
當把資料以二進位制形式存放到檔案中時,就會有-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下也行。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#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中可以看到如下定義:
1
2
3
4
5
6
7
8
9
#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)。
正確的寫法應該是:
1
2
3
4
5
6
7
int c;
c = fgetc(fp);
while(!feof(fp))
{
    printf("%X\n", c);
    c = fgetc(fp);//最後一個c的值為-1,但是無妨,因為其他所有的迴圈操作都要放在此句話上面
}
feof()可以用EOF代替嗎?不可以。fgetc返回-1時,有兩種情況:讀到檔案結尾或是讀取錯誤。因此我們無法確信檔案已經結束, 因為可能是讀取錯誤! 這時我們需要feof()。

相關文章