基本情報技術者試験の過去問と解説
[TOP] [午前分野別] [午後分野別] [キーワード索引] [令和元年秋午前] [令和元年秋午後]

平成14年 秋期 基本情報技術者 午後 問12
問12   Java

〔プログラムの説明〕

 プログラム1は,コンマ区切り( CSV 形式)のデータを解析するための汎用クラス CSVParser である。 プログラム2は,クラス CSVParser を拡張して,コンマ区切り形式の 入力データファイルをタグ付き形式の出力データに変換するプログラムである。

クラス CSVParser は,コンストラクタに指定されたコンマ区切りの データファイルをメソッド parse で解析し,次に示す状態に応じて各メソッドを呼び出す。

状態 呼び出されるメソッド 引数
ファイルの読込みを開始した startDocument なし
新しいレコードに達した startRecord n:レコード番号
レコード中のフィールドを
1項目読み込んだ
value chars:フィールドの値
n:フィールド番号
レコードの終端に達した endRecord n:レコード番号
ファイルの処理を完了した endDocument なし

 プログラム2の入力データファイル test.csv と出力結果を,それぞれ図1及び
図2に示す。

Ichiro Tanaka,tanaka@sales.example.com,111-1111

Jiro Yamada,yamada@eng.example.com,222-2222

Saburo Suzuki,suzuki@mkt.example.com,333-3333


  図1 入力データファイル test.csv

<addressbook>
  <person id="1">
    <name>Ichiro Tanaka</name>
    <email>tanakasales.example.com</email>
    <phone>111-1111</phone>
  </person>
  <person id="2">
    <name>Jiro Yamada</name>
    <email>yamadaeng.example.com</email>
    <phone>222-2222</phone>
  </person>
  <person id="3">
    <name>Saburo Suzuki</name>
    <email>suzukimkt.example.com</email>
    <phone>333-3333</phone>
  </person>
</addressbook>

     図2 出力結果

 入力データの形式は次のとおりである。

(1) 1レコードは,三つの項目からなり,各項目はコンマ(“,”)で区切られている。 レコードの終端には改行文字がある。

(2) 項目には,氏名,電子メールアドレス及び電話番号があり, 1レコード中にこれらの項目が1個ずつ,この順に並ぶ。

@ 項目にコンマが含まれることはない。

A 項目は省略できず,空白文字だけからなる項目はない。

 出力データの形式は次のとおりである。

(1) 値を開始タグと終了タグとで囲んだデータの単位を,要素と呼ぶ。

@ 開始タグは <タグ名> と記述し,終了タグは </タグ名> と記述する。

A 開始タグには,<タグ名 属性名="属性値"> という形式で,属性を記述できる。

B 以降の説明では,この要素のことを,“要素 タグ名”と呼ぶ。

(2) 要素は入れ子にすることができる。 すなわち,ある要素の中に他の要素を入れることができる。

(3) すべての開始タグと終了タグとは,対応がとれている必要がある。 すなわち,ある開始タグで始まる要素は,同じタグ名をもつ終了タグによって閉じる。

入力データ形式から出力データ形式への変換手順は,次のとおりである。

(1) 入力データ全体をまとめて,要素 addressbook を作成する。

(2) 入力データの1レコードごとに,要素 person を作成する。 要素 person には,レコードを読み込んだ順番を属性 id の値として付加する。

(3) 1レコード中の各項目から,レコード中での項目の出現の順に,name, email 及び phone の各要素をそれぞれ作成する。

テキストファイルの内容を読み込むのに,クラス java.io.FileReader を用いる。 動作は次のとおりである。

(1) コンストラクタにファイル名を示す文字列を与えると, 当該ファイルからの入力ストリームを開く。

(2) メソッド read は,入力ストリームから1文字を読み込んで int 型として返す。

(3) 入力ストリームの末尾に達した時点でメソッド read を呼び出すと,−1 を返す。

〔プログラム 1〕

import java.io.FileReader;
import java.io.IOException;
import java.io.FileNotFoundException;
public class CSVParser {
   private FileReader reader;
   public CSVParser(String fileName) throws FileNotFoundException {
      // テキスト入力ファイル用の reader を生成する。
      reader = new FileReader(fileName);
   }
   public void startDocument() {}
   public void startRecord(int n) {}
   
   public void endRecord(int n) {}
   public void endDocument() {}

   public void parse() throws IOException {
      int c;
      StringBuffer buf = new StringBuffer(); 
      boolean ;
      int fieldNumber = 0;
      int recordNumber = 0;
      startDocument();
      while ((c = reader.read()) != -1) { // reader から1文字読み込む。
         // メソッド read は入力ストリームに利用可能な文字がない場合-1を返す。
         char ch = (char)c;
         switch (ch) {
           case ',':
              ;
              buf.delete(0, buf.length());
              break;
           case '\n':
              if (!endOfRecord) {
                 endOfRecord = true;
                 ;
                 buf.delete(0, buf.length());
                 fieldNumber = 0;
                 ;
              }
              break;
           default:
              if (endOfRecord) {
                 ;
              }
              endOfRecord = false;
              ;
         }
      }
      endDocument();
   }
}

〔プログラム 2〕

import java.io.FileNotFoundException;
public class TaggedDataGenerator extends CSVParser {
   public TaggedDataGenerator(String fileName)
      throws FileNotFoundException {
      super(fileName);
   }
   public void startDocument() {
      System.out.println("<addressbook>");
   }
   public void startRecord(int n) {
      System.out.println("\t<person id=\""+n+"\">");
   }
   public void value(String chars, int n) {
      String tag = (n == 1) ? "name" : (n == 2) ? "email" : "phone";
      System.out.println("\t\t<"+tag+">"+chars+"</"+tag+">");
   }
   public void endRecord(int n) {
      System.out.println("\t</person>");
   }
   public void endDocument() {
      System.out.println("</addressbook>");
   }
   public static void main(String [] args) {
      TaggedDataGenerator parser = null;
      try { 
         parser = new TaggedDataGenerator("test.csv");
         parser.parse();
      } catch (Exception e) {
         e.printStackTrace();
      }
   }
}

基本情報技術者試験


設問  プログラム中の に入れる正しい答えを, 解答群の中から選べ。

a に関する解答群

ア public void value(StringBuffer chars, int n) {}

イ public void value(String chars, int n) {}

ウ abstract public void value(String chars, int n) {}

エ public void value(String chars, int n);

b に関する解答群

ア endOfRecord = null    イ endOfRecord = false

ウ endOfRecord = true    エ endOfRecord

c に関する解答群

ア value(buf, fieldNumber)

イ value(buf.toString(), fieldNumber)

ウ value(buf, ++fieldNumber)

エ value(buf.toString(), ++fieldNumber)

d,e に関する解答群

ア startDocument()

イ startDocument(++recordNumber)

ウ startRecord(recordNumber)

エ startRecord(++recordNumber)

オ endDocument()

カ endDocument(recordNumber)

キ endRecord()

ク endRecord(recordNumber)

f に関する解答群

ア buf += ch      イ buf[buf.length] = ch

ウ buf.append(ch)    エ buf.append(ch.toString())

解答 a ←クリックすると正解が表示されます

解答 b ←クリックすると正解が表示されます

解答 c ←クリックすると正解が表示されます

解答 d ←クリックすると正解が表示されます

解答 e ←クリックすると正解が表示されます

解答 f ←クリックすると正解が表示されます

[←前の問題] [次の問題→] [問題一覧表] [分野別] [基本情報技術者試験TOP ]