• 検索結果がありません。

データ構造とアルゴリズム論

N/A
N/A
Protected

Academic year: 2021

シェア "データ構造とアルゴリズム論"

Copied!
26
0
0

読み込み中.... (全文を見る)

全文

(1)

第3

3章

章.

.フ

ファ

ァイ

イル

ルを

を用

用い

いた

たデ

デー

ータ

タ入

入出

出力

【学習のねらい】

① データをファイルへ出力する(書き込む)方法を学習する。 ② データをファイルから入力する(読み込む)方法を学習する。 大量のデータを処理する場合は、ファイルからデータを読み込んでから処理を行います。 また、プログラムが終了すると変数に記憶されたデータは消えてしまうので、処理結果を 残すためにはファイルに保管しておくことが必要になります。このようにファイルを用い たデータ入出力はコンピュータを使った処理の場合必須の技術です。そこで本章では、Java 言語を用いたファイルによるデータ入出力の仕方を学習しましょう。

3−1 ファイルへの出力1−ファイルへの書き込み方

まず、簡単な例でデータをファイルに書き込む方法を学びましょう。次のようなフレーム を作成してください。 jTextFieldData jLabelMessage jButtonWrite そしてボタンクリック時のプログラムを次のように記述してください。 <プログラム>

void jButtonWrite_actionPerformed(ActionEvent e) { String Data=jTextFieldData.getText();

try { ⑥ // ファイル Test1.txt を出力ストリーム fw として定義する

FileWriter fw= new FileWriter("Test1.txt"); ① // fw への出力時にバッファリング機能をつける。

BufferedWriter bw= new BufferedWriter(fw); ② // さらに出力時に便利なメソッドを使用可能にする。

PrintWriter fout = new PrintWriter(bw); ③ fout.print("データ入力:"+Data); //ファイルへの書き込み ④ jLabelMessage.setText("書き込み終了しました。"); fout.close(); //ファイルを閉じる ⑤ } catch(Exception em) { ⑥ jLabelMessage.setText("エラー発生:"+em); }

(2)

加えてプログラムの先頭行に以下の波線部を加えて下さい。以下、ファイルへの入出力 を行う場合、これは必ず必要になります。 import java.awt.*; import java.awt.event.*; import javax.swing.*; import java.io.*; 見慣れない命令が目につきますが、それらの説明の前にまずは実行して動作を確認して みましょう。このプログラムは、入力文字列欄に入力した文字列を「Test1.txt」というフ ァイルに出力する(書き込む)プログラムです。確認のため、プログラムを起動させ入力 文字列欄に「これはテスト出力です。」と入力し、[書き込み]ボタンをクリックして下さ い。 すると、「待機中」というメッセージが「書き込み終了しました。」というメッセージに 変わります。このとき、プログラム(プロジェクト)と同じフォルダ内に「Test1.txt」と いうファイルができています。そこで、メモ帳や秀丸エディタなどの適当なテキストエデ ィタで開き、次のように出力されていることを確認してください。 データ入力:これはテスト出力です。 <Test1.txt> <プログラムの解説> 0.ストリームについて Java 言語では入出力データをストリームという概念で表します。ストリームとは流れと いう意味です。 流れ と言われても最初はピンと来ないかもしれませんが、大量のデータ をファイルに書き込むあるいは読み出す様は、まさにデータが流れて行くように見えるた めストリームと呼ばれるようです。Java 言語では、ファイルへのデータ入出力はストリー ムの制御(ストリームの行き着く先はどこか?→出力ファイルの指定、ストリームはどこ から来るのか→入力ファイルの指定、ストリームをどのように区切って入出力するか? 等々)を行うことによって実現されます。Java 言語では、ストリームを制御するために各 種 のク ラスを 用意 してい ます 。以下 、フ ァイル への 出力に 用い られる FileWriter、 BufferedWriter そして PrintWriter というクラスの用い方を上の例を用いて学習しましょ う。①、②などの番号は、p.33 のプログラム中の番号に対応しています。

(3)

① 出力ファイルの定義−FileWriter クラス

FileWriter fw= new FileWriter("Test1.txt");

によって、FileWriter クラスのオブジェクトを fw という名前で生成しています。一般に、 あるクラスのオブジェクトを生成するためには、 クラス名 オブジェクト名 = new クラスのコンストラクタ と記述します。クラスの定義やオブジェクトの生成については、前期テキストの第7章で 学習しました。忘れてしまった人はテキストを読み返して下さい。さて、FileWriter クラ スの場合、右辺のコンストラクタ FileWriter()のカッコ内に引数として出力ファイル名 を指定します。この文によって、ここで扱うストリームfw がファイル「Test1.txt」に流れ 着く出力ストリームとして定義されるのです。 ② 出力ストリームをバッファリング可能にする−BufferedWriter クラス ファイルへデータの出力を行う場合、データ(ストリーム)を1単位(通常はバイト単 位)毎に転送すると、フロッピィディスクやハードディスクなどファイル媒体側の受け入 れ準備ができるまで待ち時間が発生し効率が悪くなります。そこで、一旦、出力データを メモリにため込み(書き込み)、ファイル側の書き込み準備ができた段階で順次データを 書き込む処理が行われます。この処理をバッファリングと言います。

BufferedWriter bw= new BufferedWriter(fw);

によって、bw はバッファリング機能付きのストリームとなります。 ③ サービス機能を付加する−PrintWriter クラス

ファイルへのデータ出力を行う場合、PrintWriterクラスに用意されているprint()あ るいはprintln()メソッドを用いるのが普通です。*)そのため、次の文によって出力ス トリームをPrintWriterクラスの提供するサービス機能つきのストリームにしました。

PrintWriter fout = new PrintWriter(bw);

なお、上では説明のために3つに分解して記述したのですが、通常は出力ストリームの定 義は次のように1行で(一度に)記述されます。

PrintWriter fout = new PrintWriter(new BufferedWriter(new FileWriter("Test1.txt"))); 本講義でも以下ではこのように1行で記述することにします。 *)少し補足すると、FileWriter クラスにもデータを書き込む write()というメソッド が用意されているのですが、実数値を出力できない、またデータの改行を指定できな いなど、実用上不便な点が多かったので、PrinWriter クラスの print()および println()クラスが用意されたのです。

(4)

④ ファイルのクローズ

ファイル処理を終了したら、close()メソッドにより、必ずファイルを閉じなければな りません。

⑤ エラー処理−try∼catch 文

FileWriter fw= new FileWriter("Test1.txt");

などのように、出力ストリームを定義する際、何らかの理由で指定したファイルを出力フ ァイルとして確保できなかった場合、(FileWriter クラスは)IOException という例外(情 報)を発行します。Exception(例外)とは、想定通りに行かなかった場合、つまりエラ ーが発生した状態を指すプログラミング用語です。Java 言語では、Exception 情報を発 行する事を、 Exception 情報を投げる と言います。そして投げられた Exception 情報 をキャッチ(catch)して適切な処理を行うよう、文法的に義務づけています。一般に、 ファイルの入出力を行う場合、 try { ファイル入出力の処理 }

catch (Exception em){

エラーに対応した処理 } ファ イル入出力 の場合 の定型の書き方 という形で処理を記述します。今の場合、エラー処理は catch(Exception em) { jLabelMessage.setText("エラー発生:"+em); } となっており、これは、エラー情報を(ラベルに)表示させる処理を行うという意味です。 catch 文の()内の引数 em には Exception の情報、つまりエラーメッセージが書き込まれ ているのです。 少し説明が長くなりましたので、実際に色々な動作を確認することで理解を深めましょ う。上のプログラムに以下の波線部を追加して実行してみて下さい。 void jButtonWrite_actionPerformed(ActionEvent e) { String Data=jTextFieldData.getText(); try { ・・・ fout.print("データ入力:"+Data); //ファイルへの書き込み fout.print( 次の入力"); jLabelMessage.setText("書き込み終了しました。"); ・・・ 以下同じ }

(5)

先程と同様に文字列入力欄に「これはテスト出力です。」と入力してボタンをクリックする と、ファイル「Test1.txt」の内容は次のようになっているはずです。 データ入力:これはテスト出力です。次の入力 つまり、print()メソッドを連ねると、該当文字列が(横に)続けて出力されます。 それでは、 データ入力:これはテスト出力です。 次の入力 <Test1.txt> というように、改行して出力するにはどうしたらよいでしょうか? そのためには、最初の print()メソッドを println()メソッドに変更すればよいのです。次のように書き換えて 実行してみて下さい。 fout.println("データ入力:"+Data); //ファイルへの書き込み fout.print( 次の入力"); このように println()文は()内の文字列を出力後改行する、という意味を持ちます。

【基礎課題 3-1】

上の例では、文字列を採り上げましたが、整数でも同様に出力できます。 上のプログラムに波線部の修正および点線枠の追加を行って実行して下さい。 ・・・ fout.println("データ入力:"+Data); //ファイルへの書き込み fout.println("次の入力"); int a=2,b=5; fout.println("a="+a+" b="+b); fout.println("a+b="+(a+b)); jLabelMessage.setText("書き込み終了しました。"); ・・・ そして、「Test1.txt」にどのように出力されるかを確認し、枠内を埋めて下さい。 <Test1.txt の出力結果> データ入力:これはテスト出力です。 次の入力 a=2 b=5 a+b=7

(6)

<解説> 文字列同士を「+」で結ぶと、それは連結を意味する、ということはこれまで学習した通 りです。しかし、上のプログラムでは整数型と文字列型を「+」記号で結んでいます。「そ んなことが許されるのか?」と首をかしげた人もいることと思いますが、Java 言語ではこ のような書き方を認めています。そして結果を確かめてみれば分かるとおり、整数と文字 列が連結されて表示されます。例えば次のようなプログラムを考えた場合、 int a=2; String Ans="a="+a; 文字列型変数 Ans の値は「a=2」となります。このように、文字列と整数を+記号で結ぶ と、整数が自動的に文字列化され、文字列の連結として処理されます。これは非常に便利 なので、Java 言語では頻繁に利用されます。 もちろん、実数についても同様です。例えば int a=2; String Ans="a/4="+(a/4.0); というプログラムを実行すると、文字列型変数Ans の値は「a/4=0.5」となります。

(7)

3−2 ファイルへの出力2−ダイアログによるファイル名の指定

3−1節では、出力ファイル名が固定されているものとして、プログラム中で直接ファ イル名を指定していました。しかし、実際には、プログラム実行時にファイル名を指定で きた方が便利です。次の課題でその方法を学習しましょう。

【基礎課題 3-2】

前節と同様、次のようなフレームを作成してください。 jTextFieldData jLabelMessage jButtonWrite 次に、コンポーネントパレットから「Swing Containers」タブにある、「JFileChooser」 コンポーネントを選択(クリック)して下さい。 選択後、構造ペインのUIフォルダをクリックします(フ レーム上に貼り付けるのではないことに注意して下さい)。 すると、JFileChooser コンポーネントが追加されます。 以下の課題では、幾つかのファイルをデータ入出力に用います。そこで、それらファイ ルを一括して管理できるよう、適当な場所にファイル保管用のフォルダ 「IOFile」を作成しておいて下さい。フォルダ名は何でも良いのですが、 以下では、ファイル保管用フォルダ名が「IOFile」という名前であるとし て説明しています。 そしてボタンクリック時のプログラムを次ページのように作成します。

(8)

void jButtonWrite_actionPerformed(ActionEvent e) { String Data=jTextFieldData.getText(); try { // ダイアログボックスを開く jFileChooser1.showOpenDialog(this); ① // 出力ファイル名を指定する File FName=jFileChooser1.getSelectedFile(); ② // 出力ストリームを定義する

PrintWriter fout=new PrintWriter(new BufferedWriter (new FileWriter(FName))); ③ fout.println("データ入力:"+Data); //ファイルへの書き込み jLabelMessage.setText("書き込み終了しました。"); fout.close(); //ファイルを閉じる } catch(Exception em) { jLabelMessage.setText("エラー発生:"+em); } } なお、プログラムの冒頭に、 import java.io.*; を追加することを忘れないようにして下さい。ファイル名を指定している①∼③以外は前 節のプログラムと同じです。その説明は後回しにして、とりあえずプログラムを実行して みましょう。 実行後、前節同様次のような起動画面が現れます。 ここで、入力文字列欄に「これはテスト出力です。」と入力し[書き込み]ボタンをクリ ックすると・・・ 次ページのように出力ファイル指定のためのダイアログボックスが現れます。ここで、次 のように、先程作成した「IOFile」フォルダを指定します。

(9)

さらに、ファイル名として「output.txt」を入力し、[開く]ボタンをクリックすると・・・ ダイアログボックスは消え、元の画面に戻ります。 この時点で、出力ファイル「output.txt」に入力文字列欄に指定した文字列が書き込まれて います。確認のため、[IOFile]フォルダ内の「output.txt」ファイルの中身を適当なエデ ィタでチェックしてみて下さい。次のように書き込まれているはずです。 このように、JFileChooser コンポーネントを用いると、プログラム実行時に任意のファ イルを指定することができます。それでは、先程のプログラムの①∼③の意味を確認して おきましょう。 データ入力:これはテスト出力です。 <output.txt> <プログラムの解説> ① showOpenDialog()メソッドにより、ファイルを指定するダイアログボックスが表示 されます。()内は通常this を指定するものと理解しておいて下さい。 ② getSelectedFile()メソッドは、ファイルダイアログボックスで指定したファイル 名を返します。ファイル名は「File」クラス(型と考えて結構です)の変数(オブジ ェクト)に代入できます。ここでは、その変数名を「FName」としています。 ③ 下線部に示したように、今まで"output.txt"等と直接ファイル名を指定していた部 分をファイル名の変数に置き換えています。

(10)

3−3 ファイルからの入力1−ファイルからの読み込み方

さて、本章の後半では、ファイルからのデータ入力の方法を学習することにします。 例として【基礎課題3-2】で作成した出力ファイル「output.txt」を読み込んでその内容 を表示させるプログラムを考えましょう。

【基礎課題 3-3】

次のようなフレームを作成してください。 jLabelMessage jTextFieldData jButtonRead 【基礎課題3-2】と同様に入力ファイルを実行時にファイルダイアログボックスで指定する ので、p.39 と同様に JFileChooser コンポーネントを構造ペインの UI フォルダに追加して 下さい。そして、ボタンクリック時のプログラムを次のように記述します。 void jButtonRead_actionPerformed(ActionEvent e) { String Data; try { jFileChooser1.showOpenDialog(this); File FName=jFileChooser1.getSelectedFile();

BufferedReader fin=new BufferedReader ②

(new FileReader(FName)); Data=fin.readLine(); //ファイルからの読み込み ③ jTextFieldData.setText(Data); //読み込んだデータの表示 fin.close(); jLabelMessage.setText("読み込み終了しました。"); }

catch (Exception em) {

jLabelMessage.setText("エラー発生:"+em); } } ※ プログラムの冒頭に、「import java.io.*;」を追加することを忘れないように注意 して下さい。 <プログラムの解説> ① ダイアログボックスで指定した(入力)ファイル名を受け取る部分は出力ファイルの 場合と同じです。

(11)

② 入力ストリーム「fin」の指定(定義)です。出力ストリームの場合と比べて PrintWriter クラスに該当する部分がありませんが、それ以外は出力ストリームの場合と同様です。 ③ readLine()メソッドは、入力ストリーム(今の場合ファイル「FName」)から1行分 だけ読み込み、その値を文字列として返します。 プログラムの内容はほぼ理解できると思いますので早速実行して動作を確認してみまし ょう。 このプログラムを起動し、[ファイル からの入力と表示]ボタンをクリッ クします。 すると、ファイル指定のためのダ イアログボックスが現れるので、 ここで、【基礎課題3-2】で作成し た「output.txt」を指定します。 ファイル名の指定後、[開く]ボタ ンをクリックすると・・ 元 の 画 面 に 戻 り 、 フ ァ イ ル 「output.txt」の内容が表示されます。 このプログラムを用いればどの様なファイルでも、その内容を表示させることができ ます。ただし、最初の1行分だけですが・・・。

(12)

【基礎課題 3-4】− 複数行のデータの読み込み

<input.txt> 55 60 92 38 71 今度は、複数行のデータをファイルから読み込んでみましょう。入力フ ァイルとして、HP の該当部分に掲載している「input.txt」ファイルをダ ウンロードし、前節で作成したフォルダ「IOFile」にコピーして下さい。 このファイルには、次のように、あるテストの5人分の得点がデータとし て入力されています。今、このファイルからデータを読み込み、このテス トの平均点を表示するプログラムを考えましょう。 作成するプログラムの動作内容は次の通りです。 プログラムを起動すると左のよ うな画面が現れます。 ここで、[データの読み込み]ボタ ンをクリックすると・・・ jButtonRead jButtonAvg jTextFieldAvg 入力ファイルを指定するダイアロ グボックスが開きますので、ここ で、今ダウンロードしたファイル 「input.txt」を指定します。その 後[開く]ボタンをクリックする と・・・ 元の画面に戻り、表示が「読み込 み終了しました。」に変わります。 この時点で入力データの読み込み は完了しています。 続いて[平均点]ボタンをクリック すると、テストの平均点が表示され ます。

(13)

それではプログラムを作成しましょう。今の場合、簡単のためにデータの個数は5つであ ることが分かっていることにしましょう。作成に当たってポイントとなるのは次の点です。 ① 5つのデータ(得点)を保管するために、大きさが5の配列型変数を用意する。 ② ファイルから1行ずつデータを読み込む方法は【基礎課題 3-3】で分かっているので、 5つのデータを読み込むには、それを5回繰り返せば良い。 ③ 今の場合、読み込んだデータを保管する配列型変数は、ボタン[データの読み込み] とボタン[平均点]の2つのイベントハンドラ(メソッド)で共有(参照)するので、 配列型変数の宣言は、メソッドの外で行わなければならない。なぜならメソッドの中で 宣言すると、そのメソッド内でしか参照できないからである。→前期のテキスト「6-12 ローカル変数とインスタンス変数」参照。 以上を念頭に置いてプログラムを記述すると次のようになります。

int[] Tokuten=new int[5]; //得点を保管する配列 int Num; //データの個数 void jButtonRead_actionPerformed(ActionEvent e) { String Data; try { jFileChooser1.showOpenDialog(this); File FName=jFileChooser1.getSelectedFile(); BufferedReader fin=new BufferedReader

(new FileReader(FName)); // ファイルからの読み込み

Num=5; //データ個数の設定 for (int i=0;i<Num;i++) {

② Data=fin.readLine(); Tokuten[i]=Integer.parseInt(Data); } jLabelMessage.setText("読み込み終了しました。"); fin.close(); }

catch (Exception em) {

jLabelMessage.setText("エラー発生:"+em); } } void jButtonAvg_actionPerformed(ActionEvent e) { // 平均点の計算 int sum=0;

for (int i=0;i<Num;i++) {

得点の合計の計算

sum=sum+Tokuten[i]; }

double Avg= sum/(double)(Num); ③ jTextFieldAvg.setText(String.valueOf(Avg)); }

(14)

<プログラムの解説> ① 5つのデータを保管する整数型配列変数Tokuten とデータの個数を保管する整数型変 数Num を宣言します。場所は、メソッド(イベントハンドラ)の外側ならどこでも良 いのですが、ここでは、分かりやすく[データの読み込み]ボタンクリック時のイベン トハンドラの上に置きました。 ② データの個数分だけ(1行ずつ)データを読み込み、それを Tokuten[i]に順次代入 しています。データを読み込んだ段階では文字列型なので、Tokuten[i]に代入する際 には整数型への変換が必要であることに注意して下さい。 ③ ここで平均点を計算しています。Java 言語のルールにより、「整数/整数」は小数点以 下が切り捨てられ整数になる、という点に注意して下さい。そのため、分母のNum を 実数型に型キャスト(変換)しています。型キャストについては前期のテキスト p.81 を参照して下さい。 プログラム作成後は実行して動作を確認して下さい。

(15)

3−4 ファイルからの入力2−連続したデータ読み込み

【基礎課題3-4】では予め入力データの個数がわかっているものとしていましたが、実際 にはデータの個数が分からない状態で入力処理を行う場合が少なくありません。そこで次 の課題で、ファイル中のデータの個数が予め分かっていない場合に対応できるように(【基 礎課題3-4】のプログラムを)改善しましょう。

【基礎課題 3-5】

【基礎課題3-4】のプログラムにおいて、配列の大きさを下線部の様に修正し、データ読 み込み部分を枠線部の様に修正して下さい。それ以外は以前の通りです。

int[] Tokuten=new int[

100

]; //得点を保管する配列 ① int Num; //データの個数 void jButtonRead_actionPerformed(ActionEvent e) { String Data; try { jFileChooser1.showOpenDialog(this); File FName=jFileChooser1.getSelectedFile(); BufferedReader fin=new BufferedReader

(new FileReader(FName)); // ファイルからの読み込み int i=0; while ((Data=fin.readLine())!=null) { Tokuten[i]=Integer.parseInt(Data); i++; } Num=i; //データの個数の保管 ② jLabelMessage.setText("読み込み終了しました。"); fin.close(); }

catch (Exception em) {

jLabelMessage.setText("エラー発生:"+em); } } <プログラムの解説> ① 予めデータの個数が決まっていないので、予想される最大個数程度を配列の大きさに 指定しておきます。ここでは100 にしています。 ② readLine()メソッドによって、ファイル中の最終データの次を読み込んだ場合、そ こには何もないので、「null」という特別の値になります。nullは「空っぽ」という意味 です。「while ((Data=fin.readLine())!=null)」では、入力ストリームから読

(16)

み込んだ値をDataに代入し、その値が「null」ではない場合、つまりデータが存在する 限り読み込み続ける、という条件指定になっています。なお、whileループを回る回数 は「データ個数+1」なのですが、カウンタiが0 から始まっているため、最終的にi値 がそのままデータの個数になっています。 上の様に修正後、プログラムを実行し、前節同様きちんと動作することを確認して下さ い。

【基礎課題 3-6】

【基礎課題3-5】のプログラムに、以下のように最高点を求め表示するボタンを加えて下 さい。 入力ファイルを指定してデー タを読み込んだ後、[最高点] ボタンをクリックすると、最 高点が表示される。 jTextFieldMax jButtonMax 下の枠内を埋めて最高点を求めるプログラムを完成させて下さい。 void jButtonMax_actionPerformed(ActionEvent e) { int MAX=Tokuten[0];

for(int i=1; i<Num;i++) {

if(Tokuten[i]>Max) { Max=Tokuten[i]; } } jTextFieldMax.setText(String.valueOf(MAX)); } ヒント 最高点を求める処理は、「2-3 配列の応用−最大・最小を求める」の【基礎課題 2-4】(p.23) と同じです。

(17)

【応用課題 3-A】

【基礎課題3-6】に今度は、(下のように)最低点を求める処理を加えて下さい。 加えた部分

【応用課題 3-B】

HP の該当部分より、あるテストの得点の入ったファイル「score.txt」 をダウンロードして下さい。そして、【応用課題3-A】のプログラムを用い て、このテスト得点のデータの平均点および、最高点、最低点を求めて下 さい。 <score.txt> 55 90 85 38 80 ・・・ ※ このデータは100 名以上です。配列の大きさを 150 に変更して下さい。 次に、左のように、[デー タの読み込み]ボタンをク リックした時に受験者人 数を表示するように拡張 して下さい。

(18)

【応用課題 3-C】

さらに【応用課題3-B】を拡張しましょう。今、テストの得点が 50 点以上であれば合格 であるとしましょう。そこで、「score.txt」から得点を読み込んで、[合格者]ボタンをクリ ックすると、合格者数を表示する部分を加えて下さい。

(19)

3−5 1行に複数のデータがある場合のデータ読み込み

3-4 節で、ファイルからデータを読み込む際の一般的な方法を学習しました。しかし、そ こでは、1行に一つのデータが書き込まれていることが想定されていました。ところが実 際の場面では、ファイルの1行に複数のデータが書き込まれている場合が少なくありませ ん。その際は、個々のデータを区切って読み込む事が必要になります。本節では、このよ うにファイルの1行に複数のデータが存在する場合の読み込み方を学習します。

【基礎課題 3-7】

<score2.txt> HP の該当部分から、ファイル「score2.txt」をダウンロード して下さい。このファイルには右のように、あるテストの結果 が、氏名と得点という形で保管されています。そして、氏名と 得点はカンマ記号「,」で区切られています。 花形 満 ,55 轟 次郎 ,63 金田正太郎,39 鮎原こずえ,87 浅丘ユミ ,48 矢吹 丈 ,70 東 八郎 ,35 星 明子 ,77 諸星 団 ,59 伊達直人 ,44 そこで、このファイルから、氏名と得点を(別々に)読み込 み、その氏名だけを表示するプログラムを作成しましょう。(基 本的な部分は【基礎課題3-5】のプログラムと同様です。異なる のは、「氏名」と「得点」という2つのデータを読み込むという 点です。) なお、ダウンロードしたファイル「score2.txt」はこれまで同 様、フォルダ「IOFile」に保存されているものとします。 作成するプログラムの動作結果は以下の通りです。 jButtonRead jTextArea1 jButtonDisplay jLabelMessage プログラムを起動すると、次 の画面が現れます。 ここで、[データ読み込み] ボ タ ン を ク リ ッ ク す る と・・・

(20)

入力ファイルを指定するためのダ イアログボックスが現れます。 ここで、ダウンロードしたファイ ル「score2.txt」を指定し、[開く] ボタンをクリックします。 すると、データの読み込みが 完了し「読み込み終了しまし た。」というメッセージが表示 されます。 続いて[表示]ボタンをク リックすると、テキストエリ アに、読み込んだ受験者の全 員の氏名が表示されます。 なお、フレームの設計に当たっては、3-2 節で学習した通り、JFileChooser コンポーネン トを構造ペインのUI フォルダに追加しておく事を忘れないようにして下さい。 それでは、プログラムの作成に取りかかりましょう。まず、プログラムの冒頭部に以下 の2行(波線部)を追加して下さい。 import java.awt.*; import java.awt.event.*; import javax.swing.*; import java.io.*; import java.util.*; 「java.io.*」が必要なのはこれまで通りですが、「java.util.*」が必要なのは、こ の中に、複数のデータを区切って読み込む機能を有するクラスが入っている(そしてここ でそれを利用する)からです。 [データ読み込み]ボタンのイベントハンドラ、および、氏名と得点を保管する配列、 そしてデータの個数を保管する変数の宣言は次の通りです。

(21)

String[] Name=new String[100]; //氏名を保管する配列 int[] Tokuten=new int[100]; //得点を保管する配列 int Num; //データの配列 void jButtonRead_actionPerformed(ActionEvent e) { String Data; try { jFileChooser1.showOpenDialog(this); File FName=jFileChooser1.getSelectedFile(); BufferedReader fin=new BufferedReader

(new FileReader(FName)); int i=0;

while ((Data=fin.readLine())!=null) {

StringTokenizer tk=new StringTokenizer(Data,","); ① Name[i]=tk.nextToken(); Tokuten[i]=Integer.parseInt(tk.nextToken()); ② i++; } Num=i; jLabelMessage.setText("読み込み終了しました。"); fin.close(); }

catch (Exception em) {

jLabelMessage.setText("エラー発生:"+em); } } 枠線部以外は、基本的に【基礎課題3-5】と同様なので説明は省きます。ここでは、新し く出てきた「StringTokenizer」クラスについて説明すれば十分でしょう。 <StringTokenizer クラスについて>

① StringTokenizer tk=new StringTokenizer(Data,",");

によって、StringTokenizer クラスのオブジェクト(変数と考えて結構です)を「tk」と いう名前で生成しています。 一般に、「new StringTokenizer(文字列,区切り記号)」という形で生成したオブジェ クトには、「文字列」の中身が「区切り記号」で分解され、各々が順に(文字列として) 保管されます。上の例で具体的に説明しましょう。ファイルの最初の1行が変数 Data に 読み込まれとき、Data の中身は次のようになっています。 変数 Data の中身 花形 満 ,55

そして、「StringTokenizer tk=new StringTokenizer(Data,",");」によって、 Data の中身は区切り記号「,」によって分解され、tk の中身は次のようになります。

(22)

1番目のトークン 2番目のトークン tk 花形 満 55 区切られた個々の文字列を「トークン」と呼びます。 ② StringTokenizer クラスには、「nextToken()」メソッドがあり、これによりtk に 保 管 さ れ て い る ト ー ク ン を 順 に 取 り 出 す こ と が で き ま す 。 今 の 場 合 、 最 初 の nextToken()メソッドで「氏名」が取り出され、2番目の nextToken()メソッドで得 点が取り出される訳です。 以上のように、StringTokenizer クラスを利用することにより、任意の区切り記号で 区切られたデータを順次取り出すことができます。 次に、[表示]ボタンのイベントハンドラは次の通りです。 void jButtonDisplay_actionPerformed(ActionEvent e) { String Data="";

for (int i=0;i<Num;i++) { Data=Data+Name[i]+"¥n"; } jTextArea1.setText(Data); } 氏名を(1行に1名ずつ)順に表示させるので、「Name[i]+改行記号」を連結させた結 果を、jTextArea1 に表示させています。 プログラムを作成したら実行し、動作を確認して下さい。

(23)

3−6 ファイル入出力の応用

【応用課題 3-D】

【基礎課題3-7】を修正して、次のように、最高点をとった人の氏名とその得点を表示さ せるプログラムを作成して下さい。 プログラムを起動すると次の画面 が現れます。 ここで、[データの読み込み]ボタ ンをクリックすると・・・ 入力ファイル指定のダイアログ ボックスが現れるので、ここで、 「score2.txt」を指定します。 こ こ ま で の 動 作 は 【 基 礎 課 題 3-7】と同じです。 データ読み込み完了後、[最高点]ボ タンをクリックすると、最高点と、 それをとった人の氏名が表示されま す。 <ヒント> 最高点を求める部分は【基礎課題 3-6】と同様です。そこでは、 勝ち抜き戦 方式で変 数MAX に最高点候補が順次代入されて行きました。最高点候補者の氏名についても、同様 のことを行えばよいのです。

(24)

【応用課題 3-E】

【応用課題2-B】では、3択のアンケートの集計を行うプログラムを考え 回答データはテキストエリアに直接書き込んだのですが、その回答データ をファイルから読み込むようにしましょう。HP の該当部分からファイル 「Ank.txt」をダウンロードして下さい。このファイルには 150 名分の回 答結果が書き込まれています。 ました。その際 <Ank.txt> 3 2 2 2 ・・・ 作成するプログラムの動作は次の通りです。 プログラムを起動すると、次のよう な画面が現れます。 ここで、[データ読み込み]ボタンを クリックすると・・ 入力ファイル指定のダイアログ ボックスが現れるので、ここで、 ファイル「Ank.txt」を指定しま す。 データの読み込み完了後、[集計]ボ タンをクリックすると、選択肢1∼ 3それぞれの回答に対する度数が集 計され表示されます。

(25)

【応用課題 3-F】

次のような、クイック保存機能のある簡易メモ帳を作って下さい。 プログラムを起動すると次 の画面が現れます。 起動後、「メモ帳」欄に適 当にメモを記入します。 ここで、作業を中断しなけ ればならなくなったとし ます。そこで、[メモを保 存]ボタンをクリックし、 今のメモの内容を保存し ておきます。 そしてプログラムを終 了させます。

(26)

再び、プログラムを起動 し、作業を再開します。起 動後、[保存したメモを呼 び出す]ボタンをクリック します。すると、先程保存 したメモの内容が表示さ れます。 <ヒント> ① [メモを保存]ボタンをクリックしたときに、適当なファイル(プログラム中で指定) に、jTextArea コンポーネントの内容を保管する(書き込む)ようにします。 ② [保存したメモを呼び出す]ボタンをクリックしたときに、上で書き込んだファイル から1行ずつ読み込みます。要領は【基礎課題3-5】と同じです。そして、読み込んだ 内容を、jTextArea コンポーネントに表示させれば良いのです。要領は【基礎課題 3-7】 の[表示]ボタンのイベントハンドラと同様です。 <補足> jTextArea コンポーネントはそのままでは、行端で自動的に折り返してくれません。つま り意図的に改行しない限り次行へ移りません。これでは不便なので、自動的に行端で折り 返すようにするためには次のようにします。 プログラムの中ほどに、「コンポーネントの初期化」とコメントされている、jbInit() というメソッドを定義している部分があります。その中の最下部(実はメソッド内であれ ばどこでも構いません)に次の1文を加えて下さい。これは、自動折り返しを有効にする 命令です。 //コンポーネントの初期化

private void jbInit() throws Exception { ・・・

jTextArea1.setLineWrap(true); }

参照

関連したドキュメント

前章 / 節からの流れで、計算可能な関数のもつ性質を抽象的に捉えることから始めよう。話を 単純にするために、以下では次のような型のプログラム を考える。 は部分関数 (

(a) 主催者は、以下を行う、または試みるすべての個人を失格とし、その参加を禁じる権利を留保しま す。(i)

このエアコンは冷房運転時のドレン(除湿)水を内部で蒸発さ

パキロビッドパックを処方入力の上、 F8特殊指示 →「(治)」 の列に 「1:する」 を入力して F9更新 を押下してください。.. 備考欄に「治」と登録されます。

能率競争の確保 競争者の競争単位としての存立の確保について︑述べる︒

・対象書類について、1通提出のう え受理番号を付与する必要がある 場合の整理は、受理台帳に提出方

一般の地域 60dB 以下 50dB 以下 車線を有する道. 路に面する地域 65dB 以下 60dB 以下

(45頁)勿論,本論文におけるように,部分の限界を超えて全体へと先頭