課題2101
ファイル内に一行ずつ書かれている整数を読み出し、その総和を表示するプログラム TotalInFile クラスをパッケージ j2.lesson08 に作成しなさい。
このプログラムでは、まず最初にコンソールからファイル名を指定し、そのファイルの中に書かれている整数値を読み取り、最後にその合計値を表示する。
例えば、U:\ex2101sample.txt に次のようなファイルが存在したとする。
10 20 30 40 50
このプログラムを実行し、コンソールに "U:/ex2101sample.txt" と入力すると、次のように表示されるプログラムである。
ファイル名を入力:U:/ex2101sample.txt 合計は150
読み込んだファイルに整数でない値が存在する場合、次のようにエラーメッセージを出力して main メソッドを抜ける。
ファイル名を入力:U:/ex2101malformed.txt 数値に変換できません。thirty
上記の場合、U:\ex2101malformed.txt は次の内容を持つファイルである。
10 20 thirty 40 50
また、存在しないファイル "U:\ex2101notfound.txt" を指定した場合、次のように表示される。
ファイル名を入力:U:/ex2101notfound.txt U:/ex2101notfound.txtが開けませんでした。
ファイルが見つからない場合以外に IOException が発生した場合、catch 節で捕捉しないでよい (つまり、このメソッドには throws IOException の指定をすればよい)。
プログラム全体の擬似コードは次の通りである。擬似コードに従った表示を行うこと。
プログラム全体 print "ファイル名を入力:" filename = コンソール入力 (String) file = filename のファイルを読み込み用に開く if filename が開けない print filename + "が開けませんでした。", 改行 プログラムを終了 total = 各行に書かれている整数の合計 if 数値に変換できない行がある print "数値に変換できません。" + (変換できなかった文字列), 改行 プログラムを終了 print "合計は" + total
上記のプログラムは、j2.lesson08.TotalInFile クラスの main メソッドに記述すること。
手順
指定した箇所で必ずテストを行うこと。
- 詳細な擬似コードを作成する
- パッケージ j2.lesson08 にクラス TotalInFile を作成
- main メソッドを作成する
- テスト項目「TotalInFileに対する骨格テスト」をパス
- main メソッドにプログラムを書く
- テスト項目「TotalInFileに対する機能テスト」をパス
ヒント
演習で作成した FileToConsole.java と非常に似たプログラムである。FileToConsole.java の一部を書き換えるだけで、課題のプログラムを実現できる。
テストの失敗メッセージ
骨格テスト
メッセージ | 詳細 |
---|---|
(クラス名), existence | パッケージ内に課題で指定したクラスが存在していない。パッケージやクラス名を確認 |
(メンバ名), existence | 指定されたメンバが存在しない |
(メンバ名), public | メンバを作る際に public の指定がない |
(メンバ名), static | メンバを作る際に static の指定がない |
(メンバ名), type <T> | メンバを作る際に型の指定を間違っている。正しくは <T> |
機能テスト
メッセージ | 詳細 |
---|---|
期待された結果と異なります | 出力された結果が期待された値と異なる。「期待された値」と「実際の値」を比較し確認。他にも直接プログラムを実行して結果を調べたり、エラーメッセージの2行目にあるat以下を参考にプログラムを見直す |
機能テストの項目
テスト失敗時に「Results」の欄の左側に出る「test~」は、テストの項目名を表している。
項目名 | 詳細 |
---|---|
sample1 | "10", "20", "30", "40", "50" というファイルを .temp/ex2101sample1.txt に作成 |
sample2 | "1" というファイルを .temp/ex2101sample2.txt に作成 |
sample3 | "10", "20", "30", "4*10", "50" というファイルを .temp/ex2101sample3.txt に作成 |
sample4 | 存在しないファイルを指定 |
課題2102
テキストファイルを別のファイルにコピーするプログラム TextCopier クラスをパッケージ j2.lesson08 に作成しなさい。
このプログラムは、二つのファイル名を入力し、一つ目に指定したテキストファイルの内容を二つ目に指定したファイルにコピーする。
例えば、U:\ex2102sample.txt という名前の次の内容を持つファイルがあったとする。
英文を入力:Time flies like an arrow 時間は飛ぶまるでひとつの矢
このプログラムを実行し、"U:/ex2102sample.txt", "U:/ex2102copy.txt" と入力すると、次のように表示される。
コピー元のファイル名を入力:U:/ex2102sample.txt コピー先のファイル名を入力:U:/ex2102copy.txt U:/ex2102sample.txtからU:/ex2102copy.txtにコピーしました。
さらに、上記のように表示された後、U: ドライブには ex2102copy.txt というファイルが作成され、次のような内容になっている。
英文を入力:Time flies like an arrow 時間は飛ぶまるでひとつの矢
次の擬似コードに従った出力をすること。
プログラム全体 print "コピー元のファイル名を入力:" src = コンソール入力 (String) print "コピー先のファイル名を入力:" dst = コンソール入力 (String) copy(src, dst) if copy(src, dst) を実行中に例外が発生しなかった print src + "から" + dst + "にコピーしました。", 改行 else print src + "から" + dst + "にコピーできませんでした。", 改行
上記のプログラムは、j2.lesson08.TextCopier クラスの main メソッドに記述すること。
また、擬似コード中に現れる copy(src, dst) というメソッドは、次のようなメソッドである。
public static void copy(java.lang.String src, java.lang.String dst) throws java.io.IOException srcからdstにテキストファイルの内容をコピーする。 このメソッド内で例外 FileNotFoundException, IOException が発生した場合は、 このメソッド内で捕捉せずに呼び出し元で処理する必要がある。 パラメータ: src - コピー元のファイル名 dst - コピー先のファイル名 例外: java.io.IOException - コピーしようとした際に例外が発生した場合
上記の仕様を持つメソッドも j2.lesson08.TextCopier クラス内に作成し、main 内の擬似コードの該当する部分から呼び出すこと。
手順
指定した箇所で必ずテストを行うこと。
- 詳細な擬似コードを作成する
- パッケージ j2.lesson08 にクラス TextCopier を作成
- 必要なメソッドを作成する
- テスト項目「TextCopierに対する骨格テスト」をパス
- それぞれのメソッドにプログラムを書く
- テスト項目「TextCopierに対する機能テスト」をパス
ヒント
copy メソッドの「このメソッド内で捕捉せずに呼び出し元で処理する必要がある」とはつまり、「このメソッドでは例外処理を行わずに呼び出し元に任せる」という意味である。そのような場合は throws で発生する例外 (RuntimeException を除く) を指定し、そのメソッド内では例外を catch しなければよい。
また、ファイルにデータを書き込み終わったら必ず close すること。close しないとデータが確実に書き込まれず、ファイルが空のままになってしまう可能性がある。テスト実行時に実際の値が空である場合、正しく close できていない可能性がある。
テストの失敗メッセージ
骨格テスト
メッセージ | 詳細 |
---|---|
(クラス名), existence | パッケージ内に課題で指定したクラスが存在していない。パッケージやクラス名を確認 |
(メンバ名), existence | 指定されたメンバが存在しない |
(メンバ名), public | メンバを作る際に public の指定がない |
(メンバ名), static | メンバを作る際に static の指定がない |
(メンバ名), type <T> | メンバを作る際に型の指定を間違っている。正しくは <T> |
機能テスト
メッセージ | 詳細 |
---|---|
期待された結果と異なります | 出力された結果が期待された値と異なる。「期待された値」と「実際の値」を比較し確認。他にも直接プログラムを実行して結果を調べたり、エラーメッセージの2行目にあるat以下を参考にプログラムを見直す |
ファイルが開けません | コピーしたファイルが開けなかった場合 |
ファイルが空です | コピーしたファイルが空であった場合 (close されていない可能性がある) |
機能テストの項目
テスト失敗時に「Results」の欄の左側に出る「test~」は、テストの項目名を表している。
項目名 | 詳細 |
---|---|
sample1 | ".temp/ex2102sample1.txt" の内容を ".temp/ex2102copy.txt" にコピー |
sample2 | 存在しないファイル ".temp/ex2102sample2.txt" の内容を ".temp/ex2102copy.txt" にコピー |
sample3 | ".temp/ex2102sample3.txt" の内容を書き込めないファイル ".temp/ex2102copy.dir" にコピー |
課題2103 (optional)
カンマ区切りで記録された学生の得点一覧ファイルを読み出すクラス ScoreList をパッケージ j2.lesson08 に作成しなさい。
このプログラムは、次のような得点一覧ファイルを読み込み、
0000,ほげA,100 0006,ほげC,69 0010,ふーD,30 0004,ふーB,75 0003,ほげB,79 0007,ふーC,65 0002,ばーA,80 0008,ばーC,60 0005,ばーB,70 0009,ほげD,59 0001,ふーA,90 0011,ばーD,0
それぞれの行に記述されているデータをカンマ「,」区切りで順に 学籍番号, 名前, 得点 として読み込み、そのデータを取得するためのユーティリティクラスである。
読み取ったデータは、行ごとに次のクラスのインスタンスとして記憶する。
package j2.lesson08; public class Student { private final String id; private final String name; private final int score; // 学生インスタンスを作成する // - id この学生の学籍番号 // - name この学生の名前 // - score この学生の得点 public Student(String id, String name, int score) { super(); this.id = id; this.name = name; this.score = score; } // この学生の学籍番号を取得する public String getId() { return this.id; } // この学生の名前を取得する public String getName() { return this.name; } // この学生の得点を取得する public int getScore() { return this.score; } // この学生の成績を取得する public char getGrade() { if (this.score >= 80) { return 'A'; } else if (this.score >= 70) { return 'B'; } else if (this.score >= 60) { return 'C'; } else { return 'D'; } } // この学生の文字列表現を取得する public String toString() { return "id=" + getId() + ", name=" + getName() + ", score=" + getScore() + ", grade=" + getGrade(); } }
例えば、得点一覧ファイルから「0000,ほげA,100」というデータを取得した場合、
list.add(new Student("0000", "ほげA", 100));
というように、読み取ったデータを解析し、そのデータを持つインスタンスを List や配列に記憶していく。
このクラスには、次のようなコンストラクタやメソッドを記述すること。
- public ScoreList(java.lang.String filename) throws java.io.IOException
- カンマ区切りで記録された学生の得点一覧ファイルの名前を指定してインスタンスを生成する。得点一覧ファイルはカンマ区切りで順に次のように格納されている。
- 学籍番号
- 名前
- 得点
- パラメータ:
- filename - 読み出すファイルの名前
- 例外:
- java.io.IOException - 得点一覧ファイルを読み込んでいる最中に例外が発生した場合
- java.lang.NumberFormatException - 得点が整数でない場合
ファイルを読み込む場合は、このコンストラクタ内で読み込むこと。それ以外のメソッドでは throws IOException や java.lang.NumberFormatException を発生させてはならない。また、このコンストラクタ内で例外が発生した場合は、捕捉せずに throws で呼び出し元に例外処理を任せること。
- public java.util.List getAllStudent()
- 一覧に含まれる全ての学生を Student 型を格納している List で取得する。List 内の順序は、コンストラクタに指定したファイルに記述されている順番に等しい。
- 戻り値:
- 全ての学生を含む List
「Student 型を格納している List」というのは、このメソッドを呼び出した結果、返ってくる List の各要素が Student クラスのインスタンスであるということを指す。
- public java.util.List getStudents(char grade)
- 一覧に含まれる学生のうち、gradeで指定した成績を持つ学生を取得する。このクラスが返す List は該当する学生を表す Student クラスのインスタンスを全て含む。 List 内の順序は、コンストラクタに指定したファイルに記述されている順番に等しい。
- パラメータ:
- grade - 取得する学生の成績, 'A', 'B', 'C', 'D' のいずれか
- 戻り値:
- 指定した成績を持つ学生を含む List
取得する学生の成績は、Student クラスのインスタンスメソッド getGrade() の結果と等しくなるようにすること。また、指定した成績を持つ学生がいない場合は、長さ 0 の List を返すこと。
プログラムの例
まず、U:/ex2103test.txt という次の内容を持つファイルを作成する。
0000,ほげ1,100 0002,ふー2,80 0005,ばー3,60 0009,ほげ4,40 0010,ふー5,20
このファイルを読む、簡単なプログラムを書いてみる。
public static void main(String[] args) { ScoreList slist; try { slist = new ScoreList("U:/ex2103test.txt"); } catch (IOException e) { System.out.println("U:/ex2103test.txtが開けません"); return; } List all = slist.getAllStudent(); System.out.println("全体の人数=" + all.size()); List as = slist.getStudents('A'); printList('A', as); List bs = slist.getStudents('B'); printList('B', bs); List cs = slist.getStudents('C'); printList('C', cs); List ds = slist.getStudents('D'); printList('D', ds); } private static void printList(char grade, List list) { System.out.println(grade + "の学生:"); for (int i = 0; i < list.size(); i++) { System.out.println(" " + list.get(i)); } }
上記のプログラムを実行すると、次のように表示される。
全体の人数=5 Aの学生: id=0000, name=ほげ1, score=100, grade=A id=0002, name=ふー2, score=80, grade=A Bの学生: Cの学生: id=0005, name=ばー3, score=60, grade=C Dの学生: id=0009, name=ほげ4, score=40, grade=D id=0010, name=ふー5, score=20, grade=D
手順
指定した箇所で必ずテストを行うこと。
- パッケージ j2.lesson08 にクラス Student を作成
- 詳細な擬似コードを作成する
- パッケージ j2.lesson08 にクラス ScoreList を作成
- 指定したコンストラクタやインスタンスメソッドを作成する
- テスト項目「ScoreListに対する骨格テスト」をパス
- 各コンストラクタやメソッドにプログラムを書く
- テスト項目「ScoreListに対する単体テスト」をパス
テストの失敗メッセージ
骨格テスト
メッセージ | 詳細 |
---|---|
(クラス名), existence | パッケージ内に課題で指定したクラスが存在していない。パッケージやクラス名を確認 |
(メンバ名), existence | 指定されたメンバが存在しない |
(メンバ名), public | メンバを作る際に public の指定がない |
(メンバ名), not static | メンバを作る際に static が余計についている |
(メンバ名), type <T> | メンバを作る際に型の指定を間違っている。正しくは <T> |
単体テスト
メッセージ | 詳細 |
---|---|
期待された結果と異なります | メソッドを起動した結果が期待された結果と異なる。テスト項目を参照 |
例外 <E> がスローされませんでした | 例外 <E> が発生すべき場面で例外が発生しなかった |
単体テストの項目
テスト失敗時に「Results」の欄の左側に出る「test~」は、テストの項目名を表している。
項目名 | 詳細 |
---|---|
ScoreList_sample1 | new ScoreList(".temp/ex2103sample1.txt") |
ScoreList_sample2 | new ScoreList(".temp/ex2103sample2.txt") |
ScoreList_sample3 | new ScoreList(".temp/ex2103sample3.txt") |
ScoreList_sample4 | new ScoreList(".temp/ex2103sample4.txt") |
getAllStudent_sample1 | new ScoreList(".temp/ex2103sample1.txt").getAllStudent() |
getAllStudent_sample2 | new ScoreList(".temp/ex2103sample2.txt").getAllStudent() |
getStudents_A_sample1 | new ScoreList(".temp/ex2103sample1.txt").getStudents('A') |
getStudents_A_sample2 | new ScoreList(".temp/ex2103sample2.txt").getStudents('A') |
getStudents_B_sample1 | new ScoreList(".temp/ex2103sample1.txt").getStudents('B') |
getStudents_B_sample2 | new ScoreList(".temp/ex2103sample2.txt").getStudents('B') |
getStudents_C_sample1 | new ScoreList(".temp/ex2103sample1.txt").getStudents('C') |
getStudents_C_sample2 | new ScoreList(".temp/ex2103sample2.txt").getStudents('C') |
getStudents_D_sample1 | new ScoreList(".temp/ex2103sample1.txt").getStudents('D') |
getStudents_D_sample2 | new ScoreList(".temp/ex2103sample2.txt").getStudents('D') |
それぞれのファイルの内容は以下の通りである。
- .temp/ex2103sample1.txt
0000,ほげ1,100 0002,ふー2,80 0005,ばー3,60 0009,ほげ4,40 0010,ふー5,20
- .temp/ex2103sample2.txt
0000,ほげA,100 0006,ほげC,69 0010,ふーD,30 0004,ふーB,75 0003,ほげB,79 0007,ふーC,65 0002,ばーA,80 0008,ばーC,60 0005,ばーB,70 0009,ほげD,59 0001,ふーA,90 0011,ばーD,0
- .temp/ex2103sample3.txt
0000,ほげ1,A 0002,ふー2,A 0005,ばー3,C 0009,ほげ4,D 0010,ふー5,D
- .temp/ex2103sample4.txt (存在しないファイル)
課題2104 (optional)
簡単な暗号を復号するための java.io.Reader の子クラス HalReader をパッケージ j2.lesson08 に作成しなさい。
この HalReader は、次のように他の java.io.Reader と接続して使用される。
HalReader reader = new HalReader(new FileReader("U:/ex2104sample.txt"));
上記のように書くと、U:\ex2104sample.txt という暗号化されたテキストファイルを開き、その暗号を解除 (復号化) して読み出してくれる。
例えば、U:\ex2104sample.txt という暗号化されたファイルの内容が下記の通りであったとする。
Gdkkn, vnqkc! Sghr hr z rzlokd sdws ehkd enq i1.kdrrnm97.GzkQdzcdq.
これに対して、次のようなプログラムを書いて暗号を解く。
HalReader reader = new HalReader(new FileReader("U:/ex2104sample.txt")); try { while(true) { int c = reader.read(); if (c == -1) { break; } System.out.print((char) c); } } finally { reader.close(); }
上記のプログラムを実行すると、次のように表示される。
Hello, world! This is a sample text file for j2.lesson08.HalReader.
この簡単な暗号は、アルファベットと数字を1文字だけずらすことによって実現されている。
暗号化されたデータ: ZABCDEFGHIJKLMNOPQRSTUVWXY 暗号を解読したデータ: ABCDEFGHIJKLMNOPQRSTUVWXYZ 暗号化されたデータ: zabcdefghijklmnopqrstuvwxy 暗号を解読したデータ: abcdefghijklmnopqrstuvwxyz 暗号化されたデータ: 9012345678 暗号を解読したデータ: 0123456789
上記以外の文字は、暗号化しても変化は起こらない。
注意すべき点は、暗号化された文字 'Z', 'z', '9' は、解読した際にそれぞれ一周した最初の文字 'A', 'a', '0' に変換されるということである。
例えば、次の暗号化されたテキストファイル U:\ex2104abc.txt の内容が以下の通りであったとして、
ZABCDEFGHIJKLMNOPQRSTUVWXY zabcdefghijklmnopqrstuvwxy 9012345678
上記テキストファイルの内容を HalReader を接続させて複合化した場合、次のように表示される。
ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 0123456789
先ほども書いたとおり、半角の A-Z, a-z, 0-9 以外の文字は、復号化しても変化しない。つまり、次のようなファイル U:/ex2104suite.txt を HalReader を接続して読み込んだ際、
ZABCDEFGHIJKLMNOPQRSTUVWXY zabcdefghijklmnopqrstuvwxy 9012345678 あいうえお アイウエオ 0123456789
実際に取得できる文字 (文字列) は、次のような内容である。
ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 0123456789 あいうえお アイウエオ 0123456789
HalReader は java.io.Reader クラスを継承し (親クラスの誰かが継承しているだけでもよい)、上記のような振る舞いを Reader の仕様に従ってそれぞれのメソッドに定義すること。
コンストラクタは、次のものを用意すること。
- public HalReader(java.io.Reader cipher)
- 暗号化された Reader を指定して、そのストリームに接続された暗号を復号化する Reader を作成する。
- パラメータ:
- cipher - このReaderに接続する暗号化されたReader
実装すべきメソッドは次のものだけでよい。throws 指定はオーバーライド先のメソッドのそれと揃えること。
- void close()
- コンストラクタに渡された Reader を閉じる
- int read()
- コンストラクタに渡された Reader から一文字読み込み、読み込んだ内容を復号化して返す。コンストラクタに渡された Reader が終端に達していた場合、-1を返す。
- int read(char[] cbuf)
- コンストラクタに渡された Reader から cbuf.length 文字読み込み、読み込んだ内容を復号化して cbuf[0] から cbuf[cbuf.length - 1] に保存し、実際に読み込んだ文字数を返す。コンストラクタに渡された Reader が終端に達していた場合、-1を返す。
- int read(char[] cbuf, int off, int len)
- コンストラクタに渡された Reader から len 文字読み込み、読み込んだ内容を復号化して cbuf[off] から cbuf[off + len -1] に保存し、実際に読み込んだ文字数を返す。コンストラクタに渡された Reader が終端に達していた場合、-1を返す。
- long skip(long n)
- コンストラクタに渡された Reader の内容を n 文字スキップする
下記のメソッドについては、どのような動作をしてもよい。
- boolean markSupported()
- boolean ready()
- void mark(int readAheadLimit)
- void reset()
完成したら、次の暗号化された英文を解読してみよ (どこぞの国歌らしい)。
N rzx, bzm xnt rdd, ax sgd czvm'r dzqkx khfgs, Vgzs rn oqntckx vd gzhkdc zs sgd svhkhfgs'r kzrs fkdzlhmf? Vgnrd aqnzc rsqhodr zmc aqhfgs rszqr, sgqntfg sgd odqhkntr ehfgs, N'dq sgd qzlozqsr vd vzsbgdc, vdqd rn fzkkzmskx rsqdzlhmf! Zmc sgd qnbjdsr' qdc fkzqd, sgd anlar atqrshmf hm zhq, Fzud oqnne sgqntfg sgd mhfgs sgzs ntq ekzf vzr rshkk sgdqd: N rzx, cndr sgzs rszq- rozmfkdc azmmdq xds vzud N'dq sgd kzmc ne sgd eqdd zmc sgd gnld ne sgd aqzud? Nm sgd rgnqd, chlkx rddm sgqntfg sgd lhrsr ne sgd cddo, Vgdqd sgd end'r gztfgsx gnrs hm cqdzc rhkdmbd qdonrdr, Vgzs hr sgzs vghbg sgd aqddyd, n'dq sgd snvdqhmf rsddo, Zr hs ehsetkkx aknvr, mnv bnmbdzkr, mnv chrbknrdr? Mnv hs bzsbgdr sgd fkdzl ne sgd lnqmhmf'r ehqrs adzl, Hm etkk fknqx qdekdbsdc mnv rghmdr nm sgd rsqdzl: 'Shr sgd rszq-rozmfkdc azmmdq! N knmf lzx hs vzud N'dq sgd kzmc ne sgd eqdd zmc sgd gnld ne sgd aqzud! Zmc vgdqd hr sgzs azmc vgn rn uztmshmfkx rvnqd Sgzs sgd gzunb ne vzq zmc sgd azsskd'r bnmetrhnm Z gnld zmc z bntmsqx rgntkc kdzud tr mn lnqd? Sgdhq aknnc gzr vzrgdc nts sgdhq entk ennsrsdor' onkktshnm. Mn qdetfd bntkc rzud sgd ghqdkhmf zmc rkzud Eqnl sgd sdqqnq ne ekhfgs, nq sgd fknnl ne sgd fqzud: Zmc sgd rszq-rozmfkdc azmmdq hm sqhtlog cnsg vzud N'dq sgd kzmc ne sgd eqdd zmc sgd gnld ne sgd aqzud! Ng! sgtr ad hs dudq, vgdm eqddldm rgzkk rszmc Adsvddm sgdhq knudc gnldr zmc sgd vzq'r cdrnkzshnm! Akdrs vhsg uhbsnqx zmc odzbd, lzx sgd Gdzudm-qdrbtdc kzmc Oqzhrd sgd Onvdq sgzs gzsg lzcd zmc oqdrdqudc tr z mzshnm. Sgdm bnmptdq vd ltrs, enq ntq bztrd hs hr itrs, Zmc sghr ad ntq lnssn: "Hm Fnc hr ntq sqtrs." Zmc sgd rszq-rozmfkdc azmmdq hm sqhtlog rgzkk vzud N'dq sgd kzmc ne sgd eqdd zmc sgd gnld ne sgd aqzud!
手順
指定した箇所で必ずテストを行うこと。
- パッケージ j2.lesson08 にクラス HalReader を作成
- 指定したインスタンスメソッドやコンストラクタを作成する
- テスト項目「HalReaderに対する骨格テスト」をパス
- インスタンスメソッドやコンストラクタの中身を書く (演習と同様)
- main メソッドを書いて簡単なテストを行う
- JUnit を用いてもよい
- テスト項目「HalReaderに対する単体テスト」をパス
ヒント
java.io.Reader を直接継承する方法と、java.io.FilterReader を継承する方法がある。どちらを使ってもかまわない。
テスト
骨格テスト
メッセージ | 詳細 |
---|---|
(クラス名), existence | パッケージ内に課題で指定したクラスが存在していない。パッケージやクラス名を確認 |
(クラス名), extends <C> | クラスが <C> を継承していない |
(メンバ名), existence | 指定されたメンバが存在しない |
(メンバ名), public | メンバを作る際に public の指定がない |
(メンバ名), not static | メンバを作る際に static が余計についている |
(メンバ名), type <T> | メンバを作る際に型の指定を間違っている。正しくは <T> |
単体テスト
メッセージ | 詳細 |
---|---|
期待された結果と異なります | メソッドを起動した結果が期待された結果と異なる。テスト項目を参照 |
例外 <E> がスローされませんでした | 例外 <E> が発生すべき場面で例外が発生しなかった |
単体テストの項目
テスト失敗時に「Results」の欄の左側に出る「test~」は、テストの項目名を表している。
項目名 | 詳細 |
---|---|
read_sample | new HalReader(<ex2104sample と同じ内容の Reader>).read() |
read_suite | new HalReader(<ex2104suite と同じ内容の Reader>).read() |
read_test | new HalReader(<ex2104test と同じ内容の Reader>).read() |
read_throws | new HalReader(<常にIOExceptionを発生させるReader>).read() |
read_cA | new HalReader(<ex2104suite と同じ内容の Reader>).read(char[]) |
read_cA_throws | new HalReader(<常にIOExceptionを発生させるReader>).read(char[]) |
read_cAii | new HalReader(<ex2104suite と同じ内容の Reader>).read(char[], int, int) |
read_cAii_throws | new HalReader(<常にIOExceptionを発生させるReader>).read(char[], int, int) |
close_throws | new HalReader(<常にIOExceptionを発生させるReader>).close() |
- ex2104sample.txt
Gdkkn, vnqkc! Sghr hr z rzlokd sdws ehkd enq i1.kdrrnm97.GzkQdzcdq.
- ex2104suite.txt
ZABCDEFGHIJKLMNOPQRSTUVWXY zabcdefghijklmnopqrstuvwxy 9012345678 あいうえお アイウエオ 0123456789
- ex2104test.txt
N rzx, bzm xnt rdd, ax sgd czvm'r dzqkx khfgs, Vgzs rn oqntckx vd gzhkdc zs sgd svhkhfgs'r kzrs fkdzlhmf? Vgnrd aqnzc rsqhodr zmc aqhfgs rszqr, sgqntfg sgd odqhkntr ehfgs, N'dq sgd qzlozqsr vd vzsbgdc, vdqd rn fzkkzmskx rsqdzlhmf! Zmc sgd qnbjdsr' qdc fkzqd, sgd anlar atqrshmf hm zhq, Fzud oqnne sgqntfg sgd mhfgs sgzs ntq ekzf vzr rshkk sgdqd: N rzx, cndr sgzs rszq- rozmfkdc azmmdq xds vzud N'dq sgd kzmc ne sgd eqdd zmc sgd gnld ne sgd aqzud? Nm sgd rgnqd, chlkx rddm sgqntfg sgd lhrsr ne sgd cddo, Vgdqd sgd end'r gztfgsx gnrs hm cqdzc rhkdmbd qdonrdr, Vgzs hr sgzs vghbg sgd aqddyd, n'dq sgd snvdqhmf rsddo, Zr hs ehsetkkx aknvr, mnv bnmbdzkr, mnv chrbknrdr? Mnv hs bzsbgdr sgd fkdzl ne sgd lnqmhmf'r ehqrs adzl, Hm etkk fknqx qdekdbsdc mnv rghmdr nm sgd rsqdzl: 'Shr sgd rszq-rozmfkdc azmmdq! N knmf lzx hs vzud N'dq sgd kzmc ne sgd eqdd zmc sgd gnld ne sgd aqzud! Zmc vgdqd hr sgzs azmc vgn rn uztmshmfkx rvnqd Sgzs sgd gzunb ne vzq zmc sgd azsskd'r bnmetrhnm Z gnld zmc z bntmsqx rgntkc kdzud tr mn lnqd? Sgdhq aknnc gzr vzrgdc nts sgdhq entk ennsrsdor' onkktshnm. Mn qdetfd bntkc rzud sgd ghqdkhmf zmc rkzud Eqnl sgd sdqqnq ne ekhfgs, nq sgd fknnl ne sgd fqzud: Zmc sgd rszq-rozmfkdc azmmdq hm sqhtlog cnsg vzud N'dq sgd kzmc ne sgd eqdd zmc sgd gnld ne sgd aqzud! Ng! sgtr ad hs dudq, vgdm eqddldm rgzkk rszmc Adsvddm sgdhq knudc gnldr zmc sgd vzq'r cdrnkzshnm! Akdrs vhsg uhbsnqx zmc odzbd, lzx sgd Gdzudm-qdrbtdc kzmc Oqzhrd sgd Onvdq sgzs gzsg lzcd zmc oqdrdqudc tr z mzshnm. Sgdm bnmptdq vd ltrs, enq ntq bztrd hs hr itrs, Zmc sghr ad ntq lnssn: "Hm Fnc hr ntq sqtrs." Zmc sgd rszq-rozmfkdc azmmdq hm sqhtlog rgzkk vzud N'dq sgd kzmc ne sgd eqdd zmc sgd gnld ne sgd aqzud!