返回說明中心

程式開發小撇步:如何處理不確定數量的輸入 (EOF)

在編寫程式解題(OJ)時,我們常會遇到題目沒說有幾組資料,只說「讀取到檔案結尾 (EOF) 為止」。如果處理不當,程式可能會噴出錯誤訊息(如 Runtime Error)或陷入死迴圈。

核心觀念
當你不確定有多少輸入時,核心觀念是:檢查讀取函數的傳回值或狀態。一旦偵測到讀取失敗或到達檔案結尾,應立即停止迴圈。

1. PHP

在 PHP 中,讀取標準輸入的最穩健方法是使用 fgets(STDIN)

// 正確做法:判斷是否不等於 false
while (($line = fgets(STDIN)) !== false) {
    $line = trim($line); // 去除結尾換行
    if ($line === "") continue; // 視題目需求決定是否跳過空行
    
    // 開始你的邏輯
    echo "讀取到: " . $line . PHP_EOL;
}
常見錯誤:
  • 使用 while ($line = fgets(STDIN)):如果讀到內容剛好是 "0",PHP 會將其判定為 false 並提前結束迴圈。
  • 沒判斷 EOF:程式會一直嘗試讀取,導致逾時 (TLE)。

2. Python

Python 處理 EOF 非常方便,推薦直接遍歷 sys.stdin

import sys

# 推薦做法:直接遍歷 stdin
for line in sys.stdin:
    data = line.strip()
    if not data:
        continue
    # 處理邏輯
    print(f"讀取到: {data}")

或者使用 input() 配合異常處理:

while True:
    try:
        s = input()
        # 處理邏輯
    except EOFError:
        break

3. C

C 語言請檢查 scanf回傳值:成功時回傳「成功讀入的項目數」,讀到檔案結尾時回傳 EOF

#include <stdio.h>

int main(void) {
    int n;
    // 讀取整數直到 EOF
    while (scanf("%d", &n) == 1) {
        // 處理邏輯
    }

    // 或者逐行讀取:
    // char line[1024];
    // while (fgets(line, sizeof(line), stdin) != NULL) { ... }

    return 0;
}
常見錯誤:
  • 寫成 while (scanf("%d", &n) != EOF):若輸入含無法解析的字元,scanf 回傳 0(不是 EOF),會陷入死迴圈導致逾時 (TLE)。建議判斷 == 1(成功讀入的項目數)。
  • 忘記在 scanf 的變數前加 &:會直接 Runtime Error。

4. C++

C++ 的 cin 在遇到 EOF 時會自動轉換為 false

#include <iostream>
#include <string>
using namespace std;

int main() {
    string s;
    // 讀取單個單字
    while (cin >> s) {
        // 處理邏輯
    }
    
    // 或者讀取整行
    // while (getline(cin, s)) { ... }
    
    return 0;
}

5. Java

Java 建議使用 Scanner 類別的 hasNext() 系列方法。

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while (sc.hasNext()) {
            String s = sc.next();
            // 處理邏輯
            System.out.println("讀取到: " + s);
        }
    }
}

© Coding Tutor 說明中心 | 由 Antigravity AI 生成