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

C 語言文件操作深度解析(五):EOF 陷阱、fgetc 返回值與 feof 正確用法

     編輯:關於C

EOF 是什麼?

VC 中定義:#define EOF (-1)。它只是整型常量 -1,文件末尾並不存在此標誌。

錯誤示範

char ch;
while ((ch = fgetc(fp)) != EOF) {
    printf("%c\n", ch);
}

問題:fgetc 返回 int,將 0xFF 讀取時擴展為 0x000000FF(正數),賦給 char 截斷為 0xFF(有號視為 -1),誤判為 EOF。

fgetc 內部機制

  • 讀取 1 位元組,視為 unsigned char
  • 零擴展至 int 返回(高位補 0)
  • 真正 EOF 時返回 -1(0xFFFFFFFF)

正確寫法:用 int 接收

int ch;
while ((ch = fgetc(fp)) != EOF) {
    printf("%c\n", ch);
}
  • 讀 0xFA → ch = 0x000000FA(正數)
  • 讀 0xFF → ch = 0x000000FF(正數,不誤判)
  • 真 EOF → ch = 0xFFFFFFFF(-1,正確判斷)

feof 函數原理

#define _IOEOF 0x0010
#define feof(_stream) ((_stream)->_flag & _IOEOF)
  • 檢測流的 _flag 中 EOF 標誌位
  • 標誌位只有在「嘗試讀取但無數據」時才置位

feof 經典誤區

while (feof(fp) == 0) {
    ch = fgetc(fp);
    printf("%0X\n", ch);
}

輸出會多一個 FFFFFFFF,因為讀完最後一字節後標誌未置位,再讀一次才置位。

修正版

ch = fgetc(fp);
while (feof(fp) == 0) {
    printf("%0X\n", ch);
    ch = fgetc(fp);
}

符號擴展補充

unsigned char ch1 = 0xFF;  // 255
char ch2 = 0xFF;           // -1 (有號)
char ch3 = 0x73;           // 115
int a = ch1;  // 0x000000FF = 255
int b = ch2;  // 0xFFFFFFFF = -1 (符號擴展)
int c = ch3;  // 0x00000073 = 115
  • 無符號 → 零擴展
  • 有號高位 1 → 一擴展
  • 有號高位 0 → 零擴展

最佳實踐總結

  1. 讀取二進制文件必須用 int 接收 fgetc/getc 返回值
  2. 文本文件用 char 通常安全(無 0xFF),但建議統一用 int
  3. 判斷 EOF 首選 返回值 != EOF,輔助 feof/ferror 區分錯誤
  4. 讀取循環採用「先讀後判」模式
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved