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

C 語言清除 scanf 殘留緩衝區的標準做法與陷阱解析

     編輯:關於C

問題現象

int k; scanf("%d", &k);
char c; c = getchar();  // 直接讀到殘留的 '\n',導致跳過使用者輸入

scanf("%d") 讀取整數後,換行符保留在 stdin,後續 getchar()/scanf("%c") 會立即讀走它。

標準解法:手動吞噬至換行或 EOF

void clear_stdin(void) {
    int ch;
    while ((ch = getchar()) != '\n' && ch != EOF);
}

呼叫時機:scanf("%d", &k); clear_stdin();

為什麼不推薦 fflush(stdin)

  • C 標準規定 fflush 僅對輸出流或更新流有定義行為,對輸入流屬於未定義行為(UB)。
  • MSVC 擴展支援,但不可移植。

替代讀取策略:改用 fgets + sscanf

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⭐⭐⭐僅跳過空白字元,不解決整數後換行
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved