printf出力書式まとめ
最小フィールド幅 / 精度
出力書式について、前回までに以下の書式のうち、「変換指定子」、「長さ指定子」について説明した。
%[フラグ][最小フィールド幅].[精度][長さ修飾子][変換指定子]
今回は「最小フィールド幅」と「精度」である。
いずれも数値を指定し、「最小フィールド幅」は、 変換した結果がその長さ以下であった場合に、左側が空白で埋められる。
「精度」は変換指定子によって意味が異なり、 整数変換の場合、最低表示桁数を表し、足りない場合は0で埋められる。 実数変換のうち、f,e変換については、小数点以下に表示する桁数を指定することになり、指定桁以上ある場合は切り捨てられる。 また、g変換の場合は、有効数字を指定することになる。こちらも指定桁以上ある場合は切り捨てられる。 文字列の場合は最大表示文字数を表し、この数値以上の文字列は切り捨てられる。
ここで指定できるのはともに10進数値、もしくは*
(アスタリスク)である。
「精度」については、その直前にある.
(ピリオド)と合わせて記述する必要が有り、
.
(ピリオド)のみで数値を省略した場合、「精度」として、0を指定したのと同じ扱いとなる。
*
(アスタリスク)は、ここで指定する数値を引数を使って指定することを意味する。
直接その引数は出力側に変換されるわけではないのだが、一つ消費される。
これはちょっと言葉の説明だけでは難しいので、実例を見て欲しい。
では、実例。整数値の場合どうなるか。
int a = 10;
int b = 100000;
printf("[%4d]\n", a);
printf("[%4x]\n", a);
printf("[%.3d]\n", a);
printf("[%.3x]\n", a);
printf("[%4.3d]\n", a);
printf("[%4.3x]\n", a);
printf("[%*.*x]\n", 4, 3, a);
printf("[%4d]\n", b);
printf("[%.3d]\n", b);
printf("[%4.3d]\n", b);
[ 10] [ a] [010] [00a] [ 010] [ 00a] [ 00a] [100000] [100000] [100000]
と、ひと通り出力してみれば、「最小フィールド幅」「精度」がどのように影響しているか分かるだろう。 整数の場合は、いずれも「最低」文字数という形で指定するため、 それ以上の桁が必要な場合は、必要な桁分きちんと表示される。
また、*
(アスタリスク)の使い方も分かってもらえると思う。
この例では、直値を引数に書いているが、もちろん、変数でも良い。
「最小フィールド幅」「精度」を計算によって動的に求めたい場合に重宝するだろう。
こういうことはやらないだろうが、ちょっと予想と違うかもしれないパターンとして
printf("%.0d\n", 0);
と、精度0で0を出力した場合、何も表示されない。 たとえ、数値の0をあわらす0であっても、有効な桁に扱われない。 実際の桁数と同じだけ出力する、としたい場合は1を精度として指定することになる。 (デフォルトが1なので明示的に指定することはないと思うが)
次に、実数の場合の実例。
double a = 11.111111;
printf("[%15f]\n", a);
printf("[%15e]\n", a);
printf("[%15g]\n", a);
printf("[%15.2f]\n", a);
printf("[%15.2e]\n", a);
printf("[%15.2g]\n", a);
[ 11.111111] [ 1.111111e+01] [ 11.1111] [ 11.11] [ 1.11e+01] [ 11]
「最小フィールド幅」については、出力される最低文字数ということで、整数とほぼ同じ扱いとなる。 また、実数の「精度」は、デフォルトで6になっている。 しかし、同じ精度でも、e,f変換では小数点以下の桁数を表し、g変換では有効数字を指定すると、意味が異なっていることに注意。
最後に文字列、
char* a = "12345";
printf("[%10s]\n", a);
printf("[%.3s]\n", a);
printf("[%10.3s]\n", a);
printf("[%-10s]\n", a);
[ 12345] [123] [ 123] [12345 ]
文字列の場合も、「最小フィールド幅」については、出力される最低文字数という意味で、他の場合と同じになる。 「精度」は、出力する最大文字数のような意味になり、それ以上の長さの文字列の場合、途中で途切れてしまうような出力となる。 両方に同じ数値を指定することで、n文字表示する、足りない場合は空白で埋め、それ以上の場合は表示しない、 という出力指定になる。 最後の例については次回のフラグの内容になるのだが、 指定幅指定で右寄せ以外に左寄せする方法は無いのかという要望は当然あるだろうということで提示している。 詳細については次回の説明を読んでほしい。