三函數對比表
| 函數 | 頭文件 | 緩衝模式 | 回顯 | 終止條件 | 標準歸屬 |
getchar() | <stdio.h> | 行緩衝 (全緩衝) | 是 | 按下 **Enter** (\n) | C89/C99/C11 標準 |
getche() | <conio.h> | 無緩衝 (直接) | **是** | **任意鍵** 即返回 | **非標準** (DOS/Windows 專有) |
getch() | <conio.h> | 無緩衝 (直接) | **否** | **任意鍵** 即返回 | **非標準** (DOS/Windows 專有) |
關鍵行為差異演示
// getchar() - 需按 Enter
int c = getchar(); // 輸入 "abc\n" → 只讀取 'a','b' 'c' '\n' 殘留緩衝區
// getche() - 即時回顯
int c = getche(); // 輸入 'x' → 立即返回 'x',屏幕顯示 'x'
// getch() - 靜默讀取
int c = getch(); // 輸入 'y' → 立即返回 'y',屏幕**無顯示** (密碼輸入常用)
跨平台替代方案
Linux/Unix/macOS (術語:非標準輸入模式)
#include
#include
int getch_unix() {
struct termios oldt, newt;
int ch;
tcgetattr(STDIN_FILENO, &oldt);
newt = oldt;
newt.c_lflag &= ~(ICANON | ECHO); // 關閉行緩衝與回顯
tcsetattr(STDIN_FILENO, TCSANOW, &newt);
ch = getchar();
tcsetattr(STDIN_FILENO, TCSANOW, &oldt); // 恢復
return ch;
}
Windows 標準 API (無需 conio.h)
#include
#include
int getch_win() {
HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE);
DWORD mode;
GetConsoleMode(hStdin, &mode);
SetConsoleMode(hStdin, mode & ~(ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT));
char ch;
DWORD read;
ReadConsoleA(hStdin, &ch, 1, &read, NULL);
SetConsoleMode(hStdin, mode);
return ch;
}
避坑指南
- ❌ 在線程/信號處理函數中調用上述函數 — 非重入、非異步安全;
- ❌ 混用
scanf 後直接 getchar/getche — 緩衝區殘留 \n 導致「跳過輸入」;
- ✅ 統一用
fgets 讀整行,再 sscanf 解析,徹底避開緩衝區陷阱;
- ✅ 密碼輸入用平台原生 API 關閉回顯,不要用
getch 假裝安全。