int k; scanf("%d", &k);
char c; c = getchar(); // 直接讀到殘留的 '\n',導致跳過使用者輸入
scanf("%d") 讀取整數後,換行符保留在 stdin,後續 getchar()/scanf("%c") 會立即讀走它。
void clear_stdin(void) {
int ch;
while ((ch = getchar()) != '\n' && ch != EOF);
}
呼叫時機:scanf("%d", &k); clear_stdin();
fflush 僅對輸出流或更新流有定義行為,對輸入流屬於未定義行為(UB)。char line[128]; fgets(line, sizeof(line), stdin); sscanf(line, "%d", &k); // 整行讀取,自動吸收換行
優點:徹底避免殘留緩衝區,便於錯誤恢復。
#include <stdio.h>
void clear_stdin(void) {
int ch;
while ((ch = getchar()) != '\n' && ch != EOF);
}
int main(void) {
int k;
printf("請輸入整數:");
if (scanf("%d", &k) != 1) return 1;
clear_stdin(); // 關鍵步驟
char c;
printf("請輸入字元:");
c = getchar(); // 正確等待使用者輸入
printf("整數 = %d, 字元 = %c\n", k, c);
return 0;
}
bool read_int(int *out) {
char buf[64];
if (!fgets(buf, sizeof(buf), stdin)) return false;
return sscanf(buf, "%d", out) == 1;
}
後續所有互動式輸入皆建議採用「整行讀取 + 解析」模式,徹底杜緩衝區殘留問題。
| 方法 | 可移植性 | 推薦度 | 備註 |
|---|---|---|---|
| while(getchar()!='\n') | ✅ 標準 C | ⭐⭐⭐⭐⭐ | 最通用 |
| fflush(stdin) | ❌ UB | ❌ | 僅 MSVC 支援 |
| fgets + sscanf | ✅ 標準 C | ⭐⭐⭐⭐⭐ | 根治殘留,錯誤處理易 |
| scanf(" %c") 前置空格 | ✅ 標準 C | ⭐⭐⭐ | 僅跳過空白字元,不解決整數後換行 |