目次へ

5. フォーマット入出力

2005.10.11 株式会社四次元データ 宮澤了祐

J2SE5.0より追加された機能に、書式を付加した入出力機能があります。 C言語でのprintfやscanfのように、形式を指定して入出力を行うものです。 例えばある変数の値を出力するプログラムは、以下のようになります。

int a = 123;
System.out.printf("変数aの値は%dです。",a);

printf()メソッドが、標準出力に書式を指定して出力するメソッドです。 第一引数で書式情報の含まれる文字列、第二引数以下で変換される値を指定します。 このプログラムは次のように出力されます。

変数aの値は123です。

この「%d」の部分が「書式指定子」です。dの部分を「変換文字」といい、いくつか種類があります。 これらの書式付き出力を実現するメソッドは「java.util.Formatter」に実装されています。 直接このクラスを使用することも可能ですが、 System.outやSystem.errなどの標準出力ストリームで使用されているPrintStreamクラスにも、 書式付出力を可能にするメソッドが追加されました。 PrintStream.printf()及びPrintStream.format()メソッドがそれです。 この二つは名前が違うだけで同じメソッドです。

また出力されるものを文字列として生成するメソッド、format()がjava.lang.Stringに追加されました。 これは書式情報に基づき、変換を加えた文字列を出力する、staticなメソッドとして実装されています。

以下は全て同じ内容を出力します。

import java.util.Formatter;

public class FormatIOSample {
  public static void main(String[] args) {
    int a = 123;
    int b = 456;

    //PrintStreamを使用
    System.out.printf("変数a:%d 変数b:%d\n",a,b);
    System.out.format("変数a:%d 変数b:%d\n",a,b);

    //String.format()メソッドを使用
    String str = String.format("変数a:%d 変数b:%d\n",a,b);
    System.out.print(str);

    //java.util.Formatterクラスを使用。
    Formatter format = new Formatter();
    format.format("変数a:%d 変数b:%d\n",a,b);
    System.out.print(format.out());
  }
}

5.1. 書式指定子の記述方法1

書式指定子は以下のような形式で記述します。([]内は省略可能です。)

%[引数インデックス][フラグ][幅][.精度]変換文字

変換文字には次のものがあります。 大文字と小文字がある場合、大文字の変換文字を使えば変換後の値が大文字になります。

変換文字 説明 引数の型
b,B "true"または"false"に変換されます。nullは"false"に変換されます。 任意の型
h,H 16進数のハッシュ値です。nullならば"null"と出力されます。 任意の型
s,S 文字列に変換します。nullなら"null"と出力されます。 Formattableインタフェースを実装している場合はformatTo()メソッドの戻り値、 それ以外ならtoStringメソッドの戻り値です。 任意の型
c 文字列 java.lang.Character、java.lang.Byte、java.lang.Short、java.lang.Integer
d 十進数 java.lang.Byte、java.lang.Short、java.lang.Integer、java.lang.Long、java.math.BigInteger
o 八進数
x,X 16進数
e,E 指数表示 java.lang.Float、java.lang.Double、java.math.BigDecimal
f 小数
g,G 四捨五入処理後の精度および値の大きさにより、小数または指数表示
a,A 16進数の指数表示
t,T 日付と時間です。詳細は下記参照。 java.lang.Long、java.util.Calender,java.util.Date
n 改行します。 なし

ここで注意が必要なのが引数の型です。 任意の型が指定出来るs,bなどでは問題が発生しませんが、 指定出来ない型を指定してしまった場合、コンパイルの段階ではエラーが発生しません。 実行時にjava.lang.IllegalFormatConversionExceptionが発生しプログラムが停止します。

引数インデックス

C言語のprintfとの相違点の一つに、引数にインデックスをつけられる点があります。 書式指定子に対応する引数を指定出来る明示インデキシングと、相対インデキシングがあります。 以下は明示インデキシングのサンプルです。

int a1 = 1, a2 = 2, a3 = 3;
System.out.printf("a2は%2$d、a3は%3$d、a1は%1$dです。", a1, a2, a3);

次のように出力されます。

a2は2、a3は3、a1は1です。

書式指定を開始する添字%の直後に、何番目の引数かを示す数値と「$」を挿入することで、置換引数を明示的に示します。 1番目の引数を置換する場合は「%1$変換文字」といった形です。

相対インデキシングは、一つ前の書式指定子と同じ引数を使用する場合に利用できます。 相対インデキシングを用いたい場合は、「%」の直後に「<」を挿入します。

int a = 100;
System.out.printf("%dは16進数で%<x、8進数で%<oです。",a);
このように出力されます。
100は16進数で64、8進数で144です。

インデックスを指定した書式指定子と、通常の書式指定子が混在している場合、 通常の書式指定子は、インデックスを指定した書式指定子と無関係に動作します。

int a1 = 1, a2 = 2, a3 = 3;
System.out.printf("a2は%2$d、a3は%d、a1は%dです。",a1,a2,a3);

最初のみインデックスを指定しています。これは次のように出力されます。

a2は2、a3は1、a1は2です。

二番目以降の書式指定子は、先頭の書式指定子と無関係に動作しています。 それぞれ別個に処理されるものと考えてください。

↑このページの先頭へ

こちらもチェック!

PR
  • XMLDB.jp
  • シナジーマーケティング研究開発グループブログ