在編寫程式解題(OJ)時,我們常會遇到題目沒說有幾組資料,只說「讀取到檔案結尾 (EOF) 為止」。如果處理不當,程式可能會噴出錯誤訊息(如 Runtime Error)或陷入死迴圈。
在 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 並提前結束迴圈。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
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。C++ 的 cin 在遇到 EOF 時會自動轉換為 false。
#include <iostream>
#include <string>
using namespace std;
int main() {
string s;
// 讀取單個單字
while (cin >> s) {
// 處理邏輯
}
// 或者讀取整行
// while (getline(cin, s)) { ... }
return 0;
}
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);
}
}
}