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

C/C++ 輸入緩衝區處理:為什麼 fflush(stdin) 是錯誤的

     編輯:關於C++

fflush(stdin):廣泛使用但標準未定義的危險做法

許多教材與開發者習慣在 scanf 後呼叫 fflush(stdin) 清空輸入緩衝區,解決非數字輸入導致的無窮迴圈問題。但這在 C/C++ 標準中屬於未定義行為。

標準規定

C99 標準(7.21.5.2)明確指出:

若 stream 指向輸出流或最近未執行輸入操作的更新流,fflush 將未寫入資料傳送至宿主環境;否則行為未定義。

stdin 為輸入流,呼叫 fflush(stdin) 即屬「否則」情況。

為何有人覺得它「好用」?

  • MSVC (Visual C++) 將其作為擴充功能實作,可清空輸入緩衝區
  • GCC/Clang (Linux/macOS) 不支援,程式移植即失效

標準相容的清空方案

C 語言版本

int c;
while ((c = getchar()) != '\n' && c != EOF);  // 「吃掉」殘留字元

或使用 scanf("%*[^\n]"); getchar();(注意會殘留 \n)。

C++ 版本(推薦)

#include <iostream>
#include <limits>

std::cin.clear();  // 清除錯誤狀態旗標
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');  // 忽略至換行

完整範例:健壯的整數輸入迴圈

// C++ 版
int value;
while (true) {
    std::cout << "請輸入整數: ";
    if (std::cin >> value) break;  // 成功讀取整數

    if (std::cin.eof() || std::cin.bad()) break;  // 檔案結束或硬體錯誤

    std::cin.clear();  // 重置 failbit
    std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');  // 清空緩衝區
    std::cout << "輸入無效,請重試。\n";
}

核心觀念

  1. scanf/cin >> 失敗時,非法字元留在緩衝區,下次讀取會再次失敗
  2. 必須先清除錯誤狀態(clear()),再清空緩衝區(ignore() 或迴圈 getchar())
  3. 不要依賴編譯器擴充,寫出可移植的標準相容程式碼
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved