首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計疑難解答

C 語言 scanf 迴圈條件陷阱:為什麼 1==scanf(...)!=EOF 會導致 OJ 超時?

     編輯:程式設計疑難解答

OJ 題目常見讀入迴圈寫法:

while (scanf("%d", &a) != EOF) { ... }   // 正確
while (1 == scanf("%d", &a) != EOF) { ... } // 錯誤:導致超時

根本原因:運算子優先級與布林值轉換

  1. == 與 != 優先級相同,左結合。
  2. 1 == scanf(...) != EOF 等價於 (1 == scanf(...)) != EOF。
  3. scanf 成功讀入 1 個整數 → 回傳 1。
    1 == 1 → 真 (1)。
    1 != EOF (EOF 通常為 -1) → 真 (1)。
    迴圈繼續,看似正常。
  4. 但 scanf 讀取失敗 (輸入非數字) → 回傳 0。
    1 == 0 → 假 (0)。
    0 != EOF → 真 (1)。
    迴圈條件仍為真,不會跳出!
  5. 輸入緩衝區仍殘留非法字元,scanf 反覆失敗回傳 0,迴圈無限空轉 → OJ 判定超時 (TLE)。

正確寫法三選一

// 1. 最標準:直接判斷回傳值與 EOF
while (scanf("%d", &a) != EOF) { ... }

// 2. 明確判斷成功讀入個數 (推薦,語意清楚)
while (scanf("%d", &a) == 1) { ... }

// 3. C++ 風格:配合 iostream
while (cin >> a) { ... }

補充:清理緩衝區防無限迴圈

若必須用 scanf 且輸入可能含非數字,讀失敗後需手動清緩衝區:

while (true) {
    int ret = scanf("%d", &a);
    if (ret == EOF) break;          // 檔案結束
    if (ret == 1) { /* 處理 a */ continue; }
    // ret == 0:讀失敗,吃掉一個非空白字元
    scanf("%*c");                   // 或 getchar()
}

核心口訣

「不要在條件判斷裡玩花樣,scanf 回傳值直接比 EOF 或預期個數,失敗時記得清緩衝區。」

記住這原理,OJ 讀入迴圈再也不會莫名超時。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved