- Home ›
- Java入門 ›
- Scannerクラス
キーボードから入力された値を取得する
Scanner クラスの利用方法として標準入力から値を受け取りプログラムの中で利用する方法について解説します。デフォルトでは標準入力はキーボードに設定されているので、キーボードから利用者が入力した値を受け取ります。値を区切り文字を使って分割され、 Scanner クラスの next メソッドを使い順番に取得します。
(Last modified: )
目次
標準入力を使うScannerクラスのインスタンスを作成する
デフォルトでは標準入力はキーボードに設定されています(標準出力はディスプレイに設定されています)。利用者にキーボードを使って入力してもらった内容を受け取り、プログラムの中で利用するには、標準入力を入力元とする Scanner クラスのインスタンス(スキャナ)を作成します。次のコンストラクタを使用します。
public Scanner(InputStream source)
パラメータ: source - スキャン対象の入力ストリーム
1 番目の引数には入力ストリームを指定します。標準入力を指定する場合は System.in と指定してください。
実際には次のように記述します。
Scanner scanner = new Scanner(System.in);
これで標準入力であるキーボードからの入力を受け取る Scanner クラスのインスタンス(スキャナと呼びます)が作成されました。読み込まれた値は、使用している環境のデフォルト文字セットを使って文字に変換されます。
標準入力からの入力を受け取る
Scanner クラスの next メソッドを使用すると、スキャナに接続されている入力ストリームから次の文字列を受けとります。
public String next()
戻り値: 次のトークン 例外: NoSuchElementException - 利用可能なトークンがこれ以上存在しない場合 IllegalStateException - このスキャナがクローズしている場合
入力ストリームの現在の位置から次の区切り文字までの文字列を受けとります。区切り文字はデフォルトでは空白文字です。あとで解説しますが、空白文字とは半角スペースや改行などです。
入力ストリームとしてファイルや文字列を指定している場合は、次の区切り文字までの文字列を読み込みます(こちらは別のページで試します)。入力ストリームとして標準入力を指定している場合は、キーボードからの入力待ちとなります。入力が終わると入力された値の中で区切り文字までの値を読み込みます。(なお入力ストリームにまだ受け取ってない値が残っている場合はキーボードからの入力ではなくその値を受け取ります)。
次のサンプルを見てください。
import java.util.Scanner; class JSample1_1{ public static void main(String[] args){ Scanner scanner = new Scanner(System.in); System.out.println("年齢を入力してください"); String old = scanner.next(); System.out.println("年齢は" + old + "です"); } }
サンプルを実行すると next メソッドを実行した時点でキーボードからの入力待ちとなります。入力が完了するまではプログラムの実行もこの行でいったん停止します。
キーボードで値を入力し最後に Enter キーが押されるとキーボードからの入力が終わります。すると入力された値の中で区切り文字(デフォルトでは空白文字)までの値を受け取り、変数 old に格納し次の行へ処理が進みます。次の行では変数 old の値を画面に出力しています。
このようにユーザーからの入力を受け付け、その値を受け取ることができました。
デフォルトの区切り文字である空白文字について
next メソッドを実行するとデフォルトの区切り文字である空白文字までの値を取得するとここまで説明してきましたが、空白文字とは半角スペースだけではなく Character.isWhitespace() で true と判定される文字です。
具体的には次の文字がすべて空白文字として扱われます。
Unicodeの空白文字(SPACE_SEPARATOR、LINE_SEPARATOR、PARAGRAPH_SEPARATOR) \u0009 水平タブ(\t) \u000A 改行(\n) \u000B 垂直タブ \u000C 改ページ(\f) \u000D 復帰(\r) \u001C \u001D \u001E \u001F \u0020 半角スペース
Unicodeの空白文字というのは SPACE SEPARATOR (Unicode の空白文字) 、 LINE SEPARATOR (Unicode の行区切り文字) 、 PARAGRAPH SEPARATOR (Unicode の段落区切り文字) に含まれる宇文字が取り除かれます。そして全角スペース(\u3000)は SPACE SEPARATOR に含まれるため、 trim メソッドで取り除かれる文字に加えて全角スペースも取り除かれることになります。
SPACE SEPARATOR: \u0020 半角スペース SPACE \u1680 OGHAM SPACE MARK \u2000 ~ \u200A EN QUAD..HAIR SPACE \u205F MEDIUM MATHEMATICAL SPACE \u3000 全角スペース IDEOGRAPHIC SPACE LINE SEPARATOR: \u2028 PARAGRAPH SEPARATOR: \u2029
※ Unicode Character Database から抜粋しました。
※ SPACE SEPARATOR には他にノーブレークスペース と呼ばれる \u00A0 \u2007 \u202F の 3 つがありますが、 strip メソッドでは取り除かれません。
簡単に言えば、半角スペースに加えてタブや改行、全角スペースなどもすべて区切り文字の空白文字として扱われます。キーボードからの入力で、途中で空白などを挟まずに Enter キーを押して入力を完了した場合、入力した値の最後の改行文字の直前までが next メソッドの戻り値として返されます。
区切り文字を挟んで入力した複数の値を順番に受け取る
先ほどのサンプルプログラムで、キーボードから "27 東京" のように間に空白文字を挟んで入力した場合を試してみます。
next メソッドは入力ストリームから区切り文字までの値を受け取るため、入力した値の中で空白文字までの "27" だけを受け取って戻り値として返します。結果として次のようになります。
次に next メソッドを実行したときにまだ受け取っていない値がある場合、キーボードからの入力待ちになるのではなく、受け取っていない値を受け取ります。この場合は "東京" がまだ残っていたので "東京" を受け取ります。
次のサンプルを見てください。
import java.util.Scanner; class JSample1_2{ public static void main(String[] args){ Scanner scanner = new Scanner(System.in); System.out.println("年齢と出身地を空白を挟んで入力してください"); String old = scanner.next(); String pref = scanner.next(); System.out.println("年齢は" + old + "です"); System.out.println("出身地は" + pref + "です"); } }
サンプルを実行すると最初の next メソッドを実行した時点でキーボードからの入力待ちとなります。入力が完了するまではプログラムの実行もこの行でいったん停止します。
次のように "27 東京" とキーボードから入力したあと最後に Enter キーを入力します。
最初の next メソッドでは、空白文字までの "27" が戻り値として返り、変数 old に格納されます。続いて次の next メソッドが実行されますが、まだ入力ストリームに受け取られていない値があるのでキーボードからの入力待ちになるのではなく、次の空白文字までの値である "東京" が戻り値として返り、変数 pref に格納されます。
それぞれの変数に格納された値は、そのあとで画面に出力されます。
このようにキーボードから区切り文字を挟んで入力された値を next メソッドを実行するたびに順番に受け取ることができました。
なおこのサンプルプログラムで、最初の next メソッドを実行したときに "27" とだけ入力すると、次の next メソッドでは受け取る値が残っていないので再びキーボードからの入力待ちとなります。
キーボードから "東京" と入力して Enter キーを入力すると、 2 番目の next メソッドの戻り値として "東京" が返り、変数 pref に格納されます。そのあとでそれぞれの変数に格納されたいる値が画面に表示されます。
このように Scanner クラスの入力ストリームとして標準入力である System.in を指定している場合には、 next メソッドを実行したときに値が残っていればそれを受け取り、残っていなければ再びキーボードからの入力待ちとなります。
区切り文字を無視して次の行までの値を受け取る
区切り文字ではなく次の行までの値を取得するには Scanner クラスの nextLine メソッドを使います。書式は次のとおりです。
public String nextLine()
戻り値: スキップされた行 例外: NoSuchElementException - 行が見つからなかった場合 IllegalStateException - このスキャナがクローズしている場合
nextLine メソッドは入力を受け取る位置を次の行の先頭まで進めると同時に、現在位置から次の行の先頭までの間のスキップした部分の文字列を戻り値として返します。結果として次の行までの値をすべて受け取ることになります。
次のサンプルを見てください。
import java.util.Scanner; class JSample1_3{ public static void main(String[] args){ Scanner scanner = new Scanner(System.in); System.out.println("趣味を入力してください。"); String hobby = scanner.nextLine(); System.out.println("趣味は" + hobby + "です"); } }
サンプルを実行すると nextLine メソッドを実行した時点でキーボードからの入力待ちとなります。入力が完了するまではプログラムの実行もこの行でいったん停止します。
次のように "読書 映画 スポーツ" とキーボードから入力したあと最後に Enter キーを入力します。
next メソッドの場合は区切り文字までの値が戻り値として返りましたが、 nextLine メソッドの場合は改行までの値がすべて戻り値として返るため、変数 hobby には "読書 映画 スポーツ" がそのまま格納されます。変数に格納された値は、そのあとで画面に出力されます。
このように nextLine メソッドを使用することで区切り文字に関係なく改行までの入力した値をまとめて取得することができました。
なお、まとめて取得した文字列を空白文字を区切り文字として分割するには String クラスの split メソッドを使って次のように記述できます。
import java.util.Scanner; class JSample1_4{ public static void main(String[] args){ Scanner scanner = new Scanner(System.in); System.out.println("趣味を入力してください。"); String hobby = scanner.nextLine(); String[] tokens = hobby.split("\\s+"); for (int i = 0 ; i < tokens.length; i++){ System.out.println("[" + i + "]" + tokens[i]); } } }
プログラムを実行し、先ほどと同じように "読書 映画 スポーツ" と入力すると、まとめて取得した文字列を分割して画面に次のように表示します。
※ String クラスの split メソッドについては「文字列を正規表現パターンを使って分割する(String.split)」を参照されてください。
Scanner クラスには次の値を取得できるかどうかを確認する hasNext メソッドがあり、 next メソッドと組み合わせて入力された文字列を順に取得することもできるのですが、標準入力を使用している場合は次の値が取得できなくなるとキーボードからの入力待ちとなり、 hasNext がメソッドが false にならずループが終わりません。終わらせるには Ctrl + z を入力する必要があります。そこで、先ほどのように行単位でまとめて入力された値を取得したあと、 split メソッドを使って分割しています。
-- --
Scanner クラスの利用方法として標準入力から値を受け取りプログラムの中で利用する方法について解説しました。
( Written by Tatsuo Ikura )
著者 / TATSUO IKURA
これから IT 関連の知識を学ばれる方を対象に、色々な言語でのプログラミング方法や関連する技術、開発環境構築などに関する解説サイトを運営しています。