キーボードからの入力


ktermのウィンドウで起動した java プログラムは,System.out.print, System.out.printlnで文字列や数字を出力できる.それでは,キーボードから 文字列や数字を入力して変数に代入するのはどうすればいいのだろうか?

教える側からすると困ったことだが,Java言語では一行入力するというだけで も,結構やっかいな手続きが必要になっている.これは,以下のような理由に よる.

どの位やっかいか,単純に名前を読み込んで表示するプログラムを書いてみ る.
import java.io.*; // 入力に関するクラスを使う時は必要
class YourName{
   // throws IOException で内部で入出力エラーが起きる可能性があることを示す
  public static void main(String[] args) throws IOException{
  // 入力をするためには,System.inからBufferedReaderを作らなくてはいけない
    BufferedReader d=new BufferedReader(new InputStreamReader(System.in));
    // 文字列型(String)の変数 family, given を定義
    String family,given;
    System.out.println("名字を入力してください> ");
    // BufferedReader dから一行読み込んだ文字列を familyに入れる.
    family=d.readLine();
    System.out.println("名前を入力してください> ");
    // BufferedReader dから一行読み込んだ文字列を familyに入れる.
    given=d.readLine();
    // 表示する.
    System.out.println("あなたの名前は"+family+" "+given+"です");
  }
}
ここで,
import java.io.*;
は,入出力に関するクラス(ここでは,InputStreamReader,BufferedReader) を使うために必要な宣言である.
  public static void main(String[] args) throws IOException{
で,throws IOException をつけるのは,入出力をおこなうと途中でエラーが 起きることがあることを示すものだが,詳細は略す.入力を始める前には,
    BufferedReader d=new BufferedReader(new InputStreamReader(System.in));
と,BufferedReader型のオブジェクト(これは次回やる予定)を作って変数dに 入れる.ここまで準備をして,はじめて
d.readLine()
の結果,キーボードから入力した文字列がStringとして得られるようになる.

複数行を入力する場合は1行ごとにBufferedReader型のオブジェクトを作成す る必要はなく,一度作ったBufferedReader型のオブジェクト d に対して,

d.readLine();
を繰り返し実行すれば良い.同じストリームに対してBufferedReader型のオブ ジェクトを複数作成すると,キーボード入力の場合は動くように見えても標準 入力をファイルにリダイレクトすると動かなくなることがある.

文字列の比較

ユーザが入力した文字列がある文字列と一致しているかどうかをチェックするのに, 以下のように演算子「==」を使うのが自然に思える.
import java.io.*; // 入力に関するクラスを使う時は必要
class CheckTanaka{
   // throws IOException で内部で入出力エラーが起きる可能性があることを示す
  public static void main(String[] args) throws IOException{
  // 入力をするためには,System.inからBufferedReaderを作らなくてはいけない
    BufferedReader d=new BufferedReader(new InputStreamReader(System.in));
    // 文字列型(String)の変数 family を定義
    String family;
    System.out.println("名字を入力してください> ");
    family=d.readLine();
    if(family == "tanaka"){
      System.out.println("あなたの名前はおそらく田中です(田仲かもしれません).");
    }
  }
}
しかし,上のプログラムを実行してみると正しく tanaka と入力しても何も表 示されない.なぜ「==」でうまくいかないか,「==」が何を意味するかを正確 に言うと,「== はオブジェクトの identityの同一性をチェックするのであり 値の同一性をチェックするのではない」ということになるが,現時点では文字 列が等しいかどうかの比較は「==」ではできないと覚えて欲しい.

文字列の同一性を比較するには, Stringクラ ス のメソッド equalsを使って,

文字列1.equals(文字列2)
のようにする.「文字列」と書いたところは,文字列定数(「"」で囲まれるも の)の他に,文字列型の変数,文字列型の式などが許される.さきほどの式は,
import java.io.*; // 入力に関するクラスを使う時は必要
class CheckTanaka{
   // throws IOException で内部で入出力エラーが起きる可能性があることを示す
  public static void main(String[] args) throws IOException{
  // 入力をするためには,System.inからBufferedReaderを作らなくてはいけない
    BufferedReader d=new BufferedReader(new InputStreamReader(System.in));
    // 文字列型(String)の変数 family を定義
    String family;
    System.out.println("名字を入力してください> ");
    family=d.readLine();
    if(family.equals("tanaka")){
      System.out.println("あなたの名前はおそらく田中です(田仲かもしれません).");
    }
  }
}
と変更すると,
dell.tanaka.ecc.u-tokyo.ac.jp% java CheckTanaka
名字を入力してください> 
tanaka
あなたの名前はおそらく田中です(田仲かもしれません).
のように正しい結果を出す.

文字列から数値データへの変換

d.readLine()のように読み込んだデータは文字列データになっている.したがっ て,キーボードから100と入力しても得られるのは"100"という文字列で数字の 100ではない.文字列からint型へ変換するには, Integerクラス のメソッド parseIntを,String型からdouble型への変換は, Doubleクラス メソッド parseDoubleを呼び出す.
parseDouble というメソッドは,Java2から導入されたものなので, 古いバージョンのJava処理系でも動くプログラムを作る場合は, Doubleクラス のオブジェクトを作ってからメソッド doubleValueを呼び 出すようにする.
class Math5 {
  public static void main(String[] args){
    String s="1000";
    int i=Integer.parseInt(s)+1;
    System.out.println(i);
    String s1="1000.1";
    double d=Double.parseDouble(s1) * 2.0;
    System.out.println(d);
  }
}

Integer.parseInt("(1+2)") と実行して,3になってくれるなら便利だが, そのようにはなっていない.
逆に,int, double型からString型へ変換するには,Integer.toString, Double.toStringなどのメソッドが使えるが,一番簡単なのは,

  int i=10;
  String s=""+i;
のように,空の文字列に足す形にすると良い.
Java言語ではStreamTokenizer を使って入力文字の種類などの応じてトークンごとに切り分けて入力すること もできる.
import java.io.*; // 入力に関するクラスを使う時は必要
class YourName1{
   // throws IOException で内部で入出力エラーが起きる可能性があることを示す
  public static void main(String[] args) throws IOException{
  // 入力をするためには,System.inからStreamTokenizerを作る
    StreamTokenizer st=new StreamTokenizer(new InputStreamReader(System.in));
    System.out.println("名字を入力してください> ");
    while(st.nextToken() != StreamTokenizer.TT_WORD){
      System.out.println("名字を入力してください> ");
    }
    // 文字列型(String)の変数 family を定義して,トークンの文字列を入れる.
    String family=st.sval;
    System.out.println("年齢を入力してください> ");
    while(st.nextToken() != StreamTokenizer.TT_NUMBER){
      System.out.println("名字を入力してください> ");
    }
    // 実数型の変数 age を定義して,トークンの数値入れる.
    double age=st.nval;
    // 表示する.
    System.out.println(family+"さんは10年前は"+(age-10)+"歳でした");
  }
}

次に進む