經典 Java IO 練習:從鍵盤讀取「姓名 成績」每行一筆,輸入 end# 結束,計算平均分並連同明細寫入 score.txt。本文提供完整、健壯、符合現代 Java 風格的參考實作。
張三 80(空格分隔),逐行讀取。end#(題目原為 quit,以題目為準)。score.txt 包含所有明細行 + 最後一行平均分。import java.io.*;
import java.util.*;
public class RecordScore {
public static void main(String[] args) {
// 輸出檔案路徑(建議相對路徑或可配置)
File outFile = new File("score.txt");
try (
// 自動資源管理 (try-with-resources)
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new FileWriter(outFile))
) {
String line;
int count = 0;
double sum = 0.0;
System.out.println("請輸入學生姓名與成績(空格分隔),輸入 end# 結束:");
while ((line = br.readLine()) != null) {
line = line.trim();
if ("end#".equals(line)) break; // 結束條件
if (line.isEmpty()) continue; // 跳過空行
String[] parts = line.split("\\s+"); // 正則分割,支援多空格
if (parts.length < 2) {
System.err.println("格式錯誤(需:姓名 成績):" + line);
continue;
}
String name = parts[0];
double score;
try {
score = Double.parseDouble(parts[1]);
} catch (NumberFormatException e) {
System.err.println("成績非數字:" + parts[1]);
continue;
}
// 寫入明細
bw.write(line);
bw.newLine();
// 累計統計
sum += score;
count++;
}
// 輸出平均分
if (count > 0) {
double avg = sum / count;
bw.write(String.format("平均成績:%.2f", avg));
bw.newLine();
System.out.printf("統計完成:共 %d 筆,平均 %.2f,已寫入 %s%n", count, avg, outFile.getAbsolutePath());
} else {
System.out.println("無有效資料。");
}
} catch (IOException e) {
System.err.println("IO 錯誤:" + e.getMessage());
e.printStackTrace();
}
}
}
| 問題 | 原始碼 | 改進版 |
|---|---|---|
| 讀取邏輯 | String[] s=st.split("") 在迴圈外,st 為 null | 迴圈內 readLine() 後立即 split("\\s+") |
| 結束條件 | equals("quit") | equals("end#") 依題目 |
| 資源管理 | 手動 close(),異常時可能洩漏 | try-with-resources 自動關閉 |
| 平均分計算 | 邏輯錯誤、未處理除零 | 累計 sum/count,count>0 才計算 |
| 寫入平均分 | bw.write(score/count) 寫入 double 二進位 | String.format 格式化文字 |
| 異常處理 | 捕獲 ArrayIndexOutOfBoundsException 誤導 | 針對性捕獲 NumberFormatException、IOException |
ByteArrayInputStream 模擬標準輸入,驗證輸出檔案內容。java RecordScore input.txt output.txt 檔案管道模式。Files.lines() Stream API 或記憶體映射檔。new FileWriter(outFile, StandardCharsets.UTF_8) (Java 11+)。$ java RecordScore
請輸入學生姓名與成績(空格分隔),輸入 end# 結束:
張三 80
李四 90
王五 85
end#
統計完成:共 3 筆,平均 85.00,已寫入 /path/to/score.txt
$ cat score.txt
張三 80
李四 90
王五 85
平均成績:85.00
掌握 BufferedReader/Writer、try-with-resources、字串解析與異常處理,這類 IO 實務題即可輕鬆拿捏。