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
では、スキャナ・オブジェクトの使用終了時にScanner
のclose
メソッドを呼び出していることに注目してください。 スキャナはストリームではありませんが、内部で保有しているストリームの使用が終了したことを示すために、クローズする必要があります。
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
System.out
はPrintStream
クラスのオブジェクトであり、このクラスにはデフォルトのロケールをオーバーライドする方法がないためです。 正しく表示させるためには、プログラム全体のロケールをオーバーライドするか、次のトピックのフォーマットで説明するとおり、単に書式を設定することでも対応できます。