「標準入力から二つの数を読込んで、和、差、積、商を計算して、 標準出力に出力せよ。」という例題は、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 }
|
ここで詳しい理由の説明はしないが3、 scanf() をこのように使うのは良くないとされている 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、 というコードが考えられる (これはまあまあ簡単である)。 (try 〜 catch 構文については後述する (予定は…)。)
| 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% |
この結果の表示を「何か汚いように感じる」人のために次の小節がある。