このページを正しく表示するには、ブラウザでJavaScriptを有効にする必要があります。
コース: 重要なクラス
レッスン: 基本的なI/O
セクション: I/Oストリーム
サブセクション: スキャンとフォーマット
スキャン
ホームページ > 重要なクラス > 基本的なI/O

スキャン

Scanner型のオブジェクト(スキャナ)は、フォーマットされた入力データをトークンに分割し、個々のトークンをそのデータ型に従って変換するために役立ちます。

入力をトークンに分割

デフォルトでは、スキャナはトークンの区切り文字に空白文字を使用します。 (空白文字には、いわゆる空白スペースのほか、タブ、行区切り文字などがあります。 すべての一覧については、Character.isWhitespaceのドキュメントを参照してください。) スキャン処理の方法を確認するために、ScanXanを見てみましょう。これは、xanadu.txtの個々の語を読み取り、1行ずつ出力するプログラムです。
import java.io.*;
import java.util.Scanner;

public class ScanXan {
    public static void main(String[] args) throws IOException {
        Scanner s = null;
        try {
            s = new Scanner(new BufferedReader(new FileReader("xanadu.txt")));

            while (s.hasNext()) {
                System.out.println(s.next());
            }
        } finally {
            if (s != null) {
                s.close();
            }
        }
    }
}
ScanXanでは、スキャナ・オブジェクトの使用終了時にScannercloseメソッドを呼び出していることに注目してください。 スキャナはストリームではありませんが、内部で保有しているストリームの使用が終了したことを示すために、クローズする必要があります。

ScanXanの出力は次のようになります。

In
Xanadu
did
Kubla
Khan
A
stately
pleasure-dome
...
トークンの区切り文字に別の文字を使用するには、useDelimiter()の引数に正規表現を指定して呼び出します。 たとえば、トークンの区切り文字にカンマを使用する(場合によっては、カンマの後に空白が続くことがある)ときは、次のように呼び出します。
s.useDelimiter(",\\s*");

個々のトークンの変換

上記のScanXanでは、すべての入力トークンを単純なString値として扱っています。 Scannerは、Java言語のすべてのプリミティブ型(charは除く)と、BigIntegerおよびBigDecimalのトークンをサポートしています。 また、数値には桁区切り記号を使用できます。 そのため、USロケールでは、Scannerは"32,767"という文字列を、整数値を表すものとして正確に読み取ります。

ここで、ロケールについて触れておく必要があります。桁区切り記号と小数点記号は、ロケールによって異なります。 そのため、下のプログラムは、スキャナにUSロケールを使用するように指定しなかった場合、一部のロケールで正常に動作しなくなります。 このことは、通常は心配する必要はありません。一般的には、入力データのソースで使用されるロケールは、ユーザーが使用しているロケールと一致するためです。ただし、このサンプル・プログラムはJavaチュートリアルの一部として世界中に配信されているため、このような対応がされています。

サンプル・プログラムのScanSumでは、double値のリストを読み取って加算します。 ソースは次のとおりです。

import java.io.FileReader;
import java.io.BufferedReader;
import java.io.IOException;
import java.util.Scanner;
import java.util.Locale;

public class ScanSum {
    public static void main(String[] args) throws IOException {
        Scanner s = null;
        double sum = 0;
        try {
            s = new Scanner(
                    new BufferedReader(new FileReader("usnumbers.txt")));
            s.useLocale(Locale.US);


            while (s.hasNext()) {
                if (s.hasNextDouble()) {
                        sum += s.nextDouble();
                    } else {
                        s.next();
                    }   
            }
        } finally {
            s.close();
        }

        System.out.println(sum);
    }
}


サンプル入力ファイルのusnumbers.txtの内容は次のとおりです。
8.5
32,767
3.14159
1,000,000.1
出力される文字列は"1032778.74159"となります。 このピリオドは、ロケールによっては別の文字になります。System.outPrintStreamクラスのオブジェクトであり、このクラスにはデフォルトのロケールをオーバーライドする方法がないためです。 正しく表示させるためには、プログラム全体のロケールをオーバーライドするか、次のトピックのフォーマットで説明するとおり、単に書式を設定することでも対応できます。

サンプル・プログラムで問題が発生した場合は、 Compiling and Running the Examples: FAQsを参照してください。
フィードバックをお寄せください。さまざまなご意見をお待ちしております。

前のページ: スキャンとフォーマット
次のページ: フォーマット