EOF(End Of File)是 <stdio.h> 中定義的宏,通常展開為 -1(int 類型)。文件中並不存在「EOF 字符」——它是輸入函數(如 getchar、fgetc)在「讀不到數據」時返回的特殊狀態值,表示兩種情況之一:
因此,判斷文件結束應配合 feof() 與 ferror() 區分。
| 系統 | EOF 組合鍵 | 備註 |
|---|---|---|
| Linux/Unix/macOS | Ctrl+D | 發送 EOF 信號給終端驅動 |
| Windows | Ctrl+Z | 後需按 Enter 確認 |
注意: Ctrl+C 是發送 SIGINT 終止進程,非 EOF。
// ❌ 錯誤:char 無法容納 EOF(-1)
char c;
while ((c = getchar()) != EOF) { ... }
// ✅ 正確:int 可容納所有字符值 + EOF
int c;
while ((c = getchar()) != EOF) { ... }
原因: getchar() 返回 int,範圍為 0~255(字符)或 -1(EOF)。若賦值給 char(有符號時範圍 -128~127),EOF(-1) 與字符 ÿ (255) 截斷後相同,導致邏輯錯誤。K&R C 明確強調此點。
默認終端處於行緩衝(Canonical)模式:輸入需按 Enter 或 EOF 才提交給程序。此模式下 Ctrl+D 行為分三種情況:
| 輸入狀態 | 操作 | 效果 |
|---|---|---|
| 無任何輸入 | 按 Ctrl+D | 直接觸發 EOF,getchar() 返回 -1,循環結束 |
| 已輸入內容,光標在行首(剛按過 Enter) | 按 Ctrl+D | 觸發 EOF,循環結束 |
| 已輸入內容,光標不在行首 | 按一次 Ctrl+D | 提交當前緩衝區內容給程序(相當於行結束),不觸發 EOF |
| 同上 | 連按兩次 Ctrl+D | 第一次提交緩衝區,第二次觸發 EOF |
統一規律: 只有當 getchar() 等待「新的一行輸入」時,直接按 Ctrl+D 才產生 EOF;若緩衝區已有數據,Ctrl+D 只是「送交緩衝區」(行結束符)。
通過 stty raw 切換到字符模式:
system("stty raw"); // 進入字符模式:輸入即時送達,無需 Enter
c = getchar(); // 讀取單字符即返回
system("stty cooked"); // 恢復行模式
此模式下無「行結束」概念,Ctrl+D 直接作為 EOF,或作為普通控制字符(視終端設置)。
#include <stdio.h>
int main() {
int c;
while ((c = getchar()) != EOF)
putchar(c);
return 0;
}
abc + Enter → 輸出 abc + 換行,繼續等待abc + Ctrl+D → 輸出 abc(無換行),光標停留,繼續等待intfeof()/ferror()徹底理解 EOF 機制,是編寫健壯控制台程序、正確處理管道/重定向輸入的基石。