C語言中文網 目錄

feof和ferror函數,C語言feof和ferror函數詳解

正如前面所講,fgetc(或者getc)函數返回 EOF 并不一定就表示文件結束,讀取文件出錯時也會返回 EOF。即 EOF 宏不但能夠表示讀到了文件結尾這一狀態,而且還能表示 I/O 操作中的讀、寫錯誤以及其他一些關聯操作的錯誤狀態。很顯然,僅憑返回 EOF(-1) 就認為文件結束顯然是不正確的。

也正因為如此,我們需要使用 feof 函數來替換 EOF 宏檢測文件是否結束。當然,在用 feof 函數檢測文件是否結束的同時,也需要使用 ferror 函數來檢測文件讀取操作是否出錯,當 ferror 函數返回為真時就表示有錯誤發生。在實際的程序中,應該每執行一次文件操作,就用 ferror 函數檢測是否出錯。

其中,文件結束檢測函數 feof 的一般原型如下:

int feof(FILE *fp);

值得注意的是,函數 feof 只用于檢測流文件,當文件內部位置指針指向文件結束時,并未立即置位 FILE 結構中的文件結束標記,只有再執行一次讀文件操作,才會置位結束標志,此后調用 feof 才會返回為真。看下面的示例代碼:
int main(void)
{
    FILE *fp=NULL;
    char c;
    fp=fopen("myfile.txt","r");
    if(fp == NULL)
    {
        printf("不能夠訪問該文件.\n");
        exit(1);
    }
    while(!feof(fp))
    {
        c = fgetc(fp);
        printf("%c:\t%x\n",c,c);
    }
    fclose(fp);
    fp=NULL;
}
這里假設“myfile.txt”文件中存儲的是“ABCDEF”,從表面上看,該示例代碼的輸出結果應該是“ABCDEF”。但實際情況并非如此,你會發現最終輸出結果會多輸出一個結束字符EOF(這里的 EOF 是 fgetc 函數的返回值,并不是文件中存在的 EOF),運行結果如圖 1 所示。


圖 1 示例代碼的運行結果(Microsoft Visual Studio 2010)

因此,為了解決上述情況,需要在“while(!feof(fp))”循環語句中加以判斷,如下面的代碼所示:
int main(void)
{
    FILE *fp=NULL;
    char c;
    fp=fopen("myfile.txt","r");
    if(fp == NULL)
    {
        printf("不能夠訪問該文件.\n");
        exit(1);
    }
    while(!feof(fp))
    {
        c=fgetc(fp);
        if(c!=-1)
        {
            printf("%c:\t%x\n",c,c);
        }
    }
    fclose(fp);
    fp=NULL;
}
當然,也可以采用下面的這種方式進行判斷:
while(true)
{
    c=fgetc(fp);
    if(feof(fp))
    {
        break;
    }
    printf("%c:\t%x\n",c,c);
}
或者采用如下形式:
c = fgetc(fp);
while(!feof(fp))
{
    printf("%c:\t%x\n",c,c);
    c = fgetc(fp);
}
不論采用上述 3 種方式的哪一種,都能夠得到如圖 2 所示的正確結果。


圖 2 示例代碼的運行結果(Microsoft Visual Studio 2010)

正如上面所闡述的,在使用 feof 函數檢測文件是否結束的同時,還需要使用 ferror 函數來檢測文件讀取操作是否出錯,當 ferror 函數返回為真時就表示有錯誤發生。如下面的示例代碼所示:
while(!feof(fp))
{
    if(ferror(fp))
    {
        perror("error");
        break;
    }
    c=fgetc(fp);
    if(c!=-1)
    {
        printf("%c:\t%x\n",c,c);
    }
}
除此之外,最后還需要調用 clearerr 函數來清除文件出錯標志和文件結束標志,將其置為 0。如下面的示例代碼所示:
if(ferror(fp))
{
    clearerr(fp);
    /*************/
}

精美而實用的網站,提供C語言C++STLLinuxShellJavaGo語言等教程,以及socketGCCviSwing設計模式JSP等專題。

Copyright ?2011-2018 biancheng.net, 陜ICP備15000209號

底部Logo