/* * 練習問題22.8 p.570 * 現状では、readCSVTableは、それが期待する入力形式に関して、厳格すぎると同時に寛容すぎます。 * 入力の終わりに空行があるとIOExceptionをスローしますので、厳格すぎます。 * 4つ以上のカンマを持つ行でも例外が発生しませんので、寛容すぎます。 * この両方の問題を修正しなさい。 */ /* * 練習問題22.7 p.570 * 期待されるデータのセル数を引数として渡せるようにreadCSVTableを書き直しなさい。 */ package ch22.ex22_08; import java.io.IOException; import java.io.StringReader; import java.util.ArrayList; import java.util.List; import java.util.Scanner; import java.util.regex.MatchResult; import java.util.regex.Pattern; public class EX2208 { // static final int CELLS = 4; public static List<String[]> readCSVTable(Readable source, int cellsNumber) throws IOException { Scanner in = new Scanner(source); List<String[]> vals = new ArrayList<String[]>(); // String exp = "^(.*),(.*),(.*),(.*)"; StringBuffer exp = new StringBuffer("^"); Boolean nullLine = false; // 空行だったらtrue, 空行の後にも行が続くなら例外をスローする for (int i = 0; i < cellsNumber; i++) { exp.append("(.*)"); if (cellsNumber != i + 1) { exp.append(","); } } Pattern pat = Pattern.compile(exp.toString(), Pattern.MULTILINE); while (in.hasNextLine()) { if (true == nullLine) { throw new IOException("input format error"); } String line = in.findInLine(pat); if (line != null) { // String[] cells = new String[CELLS]; String[] cells = new String[cellsNumber]; MatchResult match = in.match(); // for (int i = 0; i < CELLS; i++) for (int i = 0; i < cellsNumber; i++) { cells[i] = match.group(i + 1); if (cells[i].indexOf(",") != -1) { throw new IOException("Comma number maybe incorrect. "); } } vals.add(cells); in.nextLine(); // 改行を読み飛ばし } else { nullLine = true; in.nextLine(); // 改行を読み飛ばし // throw new IOException("input format error"); } } IOException ex = in.ioException(); if (ex != null) { throw ex; } return vals; } public static void main(String[] args) { // StringReader test = new StringReader("1, 2, 3, 4\n5, 6, 7, 8\n"); // StringReader test = new StringReader("1, 2, 3\n4, 5, 6\n\n7, 8, 9\n\n"); // input format error case // StringReader test = new StringReader("1, 2, a, 3\n4, 5, 6\n7, 8, 9\n\n"); // comma number incorrect case StringReader test = new StringReader("1, 2, 3\n4, 5, 6\n7, 8, 9\n\n"); // normal case List<String[]> result = null; try { // result = EX2208.readCSVTable(test); result = EX2208.readCSVTable(test, 3); for (int i = 0; i< result.size(); i++) { System.out.print(i + ": "); for (int j = 0; j < result.get(i).length; j++) { System.out.print(result.get(i)[j] + " "); } System.out.println(""); } } catch (Exception e) { System.out.println(e); } } }