next up previous contents
Next: 2.4 書式の指定 Up: 2 標準入出力を使ったアプリケーション Previous: 2.2 Hello world

2.3 標準入力からのデータの読込み

「標準入力から二つの数を読込んで、和、差、積、商を計算して、 標準出力に出力せよ。」という例題は、Fortran, Pascal, C, C++ などでは、 よく取り上げられる。

C の場合、入門書には、次のような scanf() を用いた プログラムが載っている。

readwrite1.c

   1 /*
   2  * readwrite1.c
   3  */
   4 
   5 #include <stdio.h>
   6 
   7 int main()
   8 {
   9   double a, b, wa, sa, seki, syou;
  10   printf("二つの数を入力してください: ");
  11   scanf("%lf%lf", &a, &b);
  12   wa = a + b;
  13   sa = a - b;
  14   seki = a * b;
  15   syou = a / b;
  16   printf("和=%g, 差=%g, 積=%g, 商=%g\n", wa, sa, seki, syou);
  17   return 0;
  18 }

ここで詳しい理由の説明はしないが3scanf() をこのように使うのは良くないとされている 4(ある意味で scanf() は悪名高い関数である)。 入力を文字列として読んでから、文字列を解析することが推奨されている。 例えば以下のプログラムのようになる。

readwrite2.c

   1 /*
   2  * readwrite2.c
   3  */
   4 
   5 #include <stdio.h>
   6 
   7 int main()
   8 {
   9   char buf[BUFSIZ];
  10   double a, b, wa, sa, seki, syou;
  11   printf("二つの数を入力してください: ");
  12   /* 一行読込む */
  13   fgets(buf, sizeof(buf), stdin);
  14   /* buf[] の内容を sscanf() で解析する */
  15   if (sscanf(buf, "%lf%lf", &a, &b) != 2) {
  16     fprintf(stderr, "Input Error\n");
  17     exit(1);
  18   }
  19   wa = a + b;
  20   sa = a - b;
  21   seki = a * b;
  22   syou = a / b;
  23   printf("和=%g, 差=%g, 積=%g, 商=%g\n", wa, sa, seki, syou);
  24   return 0;
  25 }

さて、Java ではどうするか?実は初心者には結構な難題である。 Java には scanf()sscanf() も存在しない。 これは scanf 系の関数が複雑過ぎるというのが一つの理由であろう (色々なエラーが起こり得るものを一つの関数に押し込めると、 エラーの解析が大変である)。 もう一つは、 Java の主たる応用では、 ユーザー・インターフェイスは標準入出力よりは GUI であり、 もともと複雑な入力を解析する必要性が低いためであろう5

一行に一つの数値しかないのであれば、 次の ReadWrite1.java のように、 readLine() メソッドを使って文字列として読込み、 Double.valueof().doubleValue(文字列) を 使って double の値に変換する 6、 というコードが考えられる (これはまあまあ簡単である)。 (trycatch 構文については後述する (予定は…)。)

ReadWrite1.java

   1 /*
   2  * ReadWrite1.java
   3  */
   4 
   5 import java.util.*;  // StringTokenizer
   6 import java.io.*;    // BufferedReader
   7 
   8 public class ReadWrite1 {
   9   public static void main(String args[]) {
  10     double a, b, wa, sa, seki, syou;
  11 
  12     BufferedReader d = new BufferedReader(new InputStreamReader(System.in));
  13     try {
  14       System.out.print("数を入力してください: ");
  15       a = Double.valueOf(d.readLine()).doubleValue();
  16       System.out.print("数を入力してください: ");
  17       b = Double.valueOf(d.readLine()).doubleValue();
  18       wa = a + b;
  19       sa = a - b;
  20       seki = a * b;
  21       syou = a / b;
  22       System.out.println("和=" + wa + ", 差=" + sa
  23                          + ", 積=" + seki + ", 商=" + syou);
  24     }
  25     catch(IOException e) {
  26       System.out.println("IO Error");
  27       System.exit(1);
  28     }
  29   }
  30 }

一行の入力に二つ以上の数値を含める場合には、 一つの数を表わす文字列を切り出してから、 Double.valueof().doubleValue() を使って double の値に変換する、 という手順になる。 文字列の切り出しには StringTokenizer を用いる。 まとめると、次の ReadWrite2.java のようになる。

ReadWrite2.java

   1 /*
   2  * ReadWrite2.java
   3  */
   4 
   5 import java.util.*;  // StringTokenizer
   6 import java.io.*;    // BufferedReader
   7 
   8 public class ReadWrite2 {
   9   public static void main(String args[]) {
  10     double a, b, wa, sa, seki, syou;
  11     System.out.print("二つの数を入力してください: ");
  12 
  13     BufferedReader d = new BufferedReader(new InputStreamReader(System.in));
  14     try {
  15       String str = d.readLine();
  16       StringTokenizer aSt = new StringTokenizer(str," ");
  17       if (aSt.countTokens() != 2) {
  18         System.out.print("Input Error\n");
  19         System.exit(1);
  20       }
  21       a = Double.valueOf(aSt.nextToken()).doubleValue();
  22       b = Double.valueOf(aSt.nextToken()).doubleValue();
  23       wa = a + b;
  24       sa = a - b;
  25       seki = a * b;
  26       syou = a / b;
  27       System.out.println("和=" + wa + ", 差=" + sa
  28                          + ", 積=" + seki + ", 商=" + syou);
  29     }
  30     catch(IOException e) {
  31       System.out.println("IO Error");
  32       System.exit(1);
  33     }
  34   }
  35 }

ReadWrite1, ReadWrite2 の実行

   1 yurichan% java ReadWrite1
   2 数を入力してください: 12.34
   3 数を入力してください: 56.78
   4 和=69.12, 差=-44.44, 積=700.6652, 商=0.2173300457907714
   5 yurichan% java ReadWrite2
   6 二つの数を入力してください: 12.34 56.78
   7 和=69.12, 差=-44.44, 積=700.6652, 商=0.2173300457907714
   8 yurichan% 

この結果の表示を「何か汚いように感じる」人のために次の小節がある。


next up previous contents
Next: 2.4 書式の指定 Up: 2 標準入出力を使ったアプリケーション Previous: 2.2 Hello world
Masashi Katsurada
平成20年2月28日