首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C語言檔案讀寫:feof() 判斷檔案結束的正確用法與陷阱避坑

     編輯:關於C語言

C語言檔案讀寫:feof() 判斷檔案結束的正確用法與陷阱避坑

為什麼需要 feof()?

文本檔以 ASCII 儲存,數值範圍 0~255,可用 EOF (-1) 作結束標記。但二進位檔內容可能包含 0xFF (-1),若以 EOF 判斷會誤判提前結束。ANSI C 提供 feof(FILE *fp):

  • 回傳 非零 (true):已讀至檔案結尾。
  • 回傳 零 (false):尚未結尾。

適用於文本與二進位檔,是更通用的做法。

完整範例:檔案複製程式


#include <stdio.h>
#include <stdlib.h>

/* 複製檔案:逐字元讀寫 */
void filecopy(FILE *fpin, FILE *fpout) {
    int ch = getc(fpin);           /* 先讀一字元,處理空檔案 */
    while (!feof(fpin)) {          /* feof 非零表示已到結尾 */
        putc(ch, fpout);
        ch = getc(fpin);
    }
}

int main() {
    FILE *fpin, *fpout;

    fpin = fopen("D:\\TEST\\file_a.dat", "r");
    if (fpin == NULL) {
        printf("Can't open source file!\n");
        exit(EXIT_FAILURE);
    }

    fpout = fopen("D:\\TEST\\file_b.dat", "w");
    if (fpout == NULL) {
        printf("Can't create target file!\n");
        fclose(fpin);
        exit(EXIT_FAILURE);
    }

    filecopy(fpin, fpout);

    fclose(fpin);
    fclose(fpout);
    return 0;
}

關鍵細節解析

  1. 先讀後判:迴圈前必須先呼叫一次 getc(),否則 feof() 在尚未嘗試讀取時永遠回傳 0,導致空檔案不進迴圈、或漏讀最後一字元。
  2. 回傳型別:getc()/fgetc() 回傳 int 而非 char,以便容納 EOF (-1);變數宣告為 int ch。
  3. 錯誤處理:fopen 失敗回傳 NULL,必須檢查並釋放已開啟資源。
  4. 二進位模式:Windows 下複製圖片、執行檔請用 "rb"/"wb",避免 \r\n 轉換損壞資料。

常見錯誤與正確寫法對照

錯誤寫法問題正確寫法
while (!feof(fp)) { ch = getc(fp); ... }若檔案為空,迴圈仍執行一次,ch=EOF 寫入輸出先 ch=getc(fp),再 while(!feof(fp))
char ch; while((ch=getc(fp))!=EOF)char 無法區分 0xFF 與 EOFint ch; while((ch=getc(fp))!=EOF)
忽略 ferror()讀取錯誤(如磁碟壞軌)會被誤判為 EOF迴圈後檢查 if (ferror(fp)) perror("read error")

進階:二進位塊讀寫 fread/fwrite

大量資料建議使用緩衝區:


#define BUFSZ 4096
char buf[BUFSZ];
size_t n;
while ((n = fread(buf, 1, BUFSZ, fpin)) > 0) {
    fwrite(buf, 1, n, fpout);
}
if (ferror(fpin)) perror("read error");

此法效能較佳,且自然處理檔案結束(fread 回傳 0 即結尾或出錯)。

總結

  • feof() 是判斷檔案結束的標準方式,適用文本與二進位檔。
  • 採用「先讀、再判、後處理」模式,避免邊界錯誤。
  • 讀取函式回傳值型別用 int,配合 ferror() 區分錯誤與正常結尾。
  • 大檔案優先考慮 fread/fwrite 區塊操作。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved