printfと変数の型
〜出力文字列(変換文字)
(準備中)
Printfは標準出力(stdout)への出力関数です。一般的に標準出力はデフォルトでディスプレイ
になっています。
Printfの出力文字列には制御文字や変換文字を含むことができます。=書式付文字列
書式のまとめ
制御文字
\n 改行 \t タブ
\b バックスペース \" "を表示
\\ \を表示 \r キャリlリジリターン \0 ヌル文字
変換文字
以下はANSI C89に基づいた説明です。
変換文字の先頭には%を付けます。
その後ろには以下のような変換文字を付けます。
d 整数型。10進数
x 整数型。16進数
o 整数型。8進数
u 符号なし整数。10進数
c 文字
s 文字列(ただしnull=00は出力しない)
e 実数型 float型でもdouble型でもいい ±n.nnE±mm の形式で出力
f 実数型 float型でもdouble型でもいい(※) ±n.nnの形式で出力
g 実数型 float型でもdouble型でもいい(※)。%fと%eのうちフィールド幅の短い方の形式で自動的に表示する。
変換指示は更に細かく指示することができます。
数字で出力桁数を指定する。 %5d とすると整数型を5ケタで出力します。
-をつけると左詰めの表示をする。 %-5d 左詰で5ケタの出力
0をつけるとゼロでパディングする。 %05d 先頭を0でパディングし5ケタ出力
n.mf 実数値でフィールド幅と小数点以下のケタ数を指定 %8.2f 8桁の出力で小数点以下は2ケタ
lを付けてldとすると 倍長整数long型の表示 %9ldとすると倍長整数型を9ケタで出力
lを付けてlfとするとlong double型の表示
以下はBorland C++5.5でのプログラム例
[printf.c]
#include <stdio.h>
int main(void){
int a;
a=1234;
printf("%d\n",a);
printf("%8d\n",a);
printf("%-8d\n",a);
printf("%08d\n",a);
printf("16進数 %x\n",a);
return 0;
}
実行例
c:\bcc55\Bin>printf
1234
1234
1234
00001234
16進数 4d2
(※)
Cは演算時にfloat型がdouble型に自動昇格することがあります。
printf()の中でもfloat型はdouble型に自動昇格するようなので、%fという変換文字はfloat型でも
double型でもどちらでも使えるということになるようです。
%lfはdouble型変数への変換文字ですが、Borland C++5.5の仕様では、%lfは%fと同じl結果になり
float型、double型どちらも、%fを使っても%lfを使ってもいいということになるようです。
このあたりはコンパイラによって異なってくる部分なので、お使いのコンパイラの仕様を確認しないと
バグの温床になります。
scanfでの入力時も同様の制御文字、変換文字を使いますが、scanfで使う時は入力する変数の型に応じて、
float型には%fとdouble型には%lfをきちんと使い分けないと、正しい値の入力ができません。
[print.c]
#include <stdio.h> int main(void) { int i; long l; float f; double db; i=32767; l=123456789; f=3.1415; db=3.141592653; printf("hd:%hd d:%d ld:%ld\n",i,i,i); printf("hd:%hd d:%d ld:%ld\n",l,l,l); printf("f:%f lf:%lf\n",f,f); printf("f:%f lf:%lf\n",db,db); printf("f:%10.9f lf:%10.9lf\n",db,db); return 0; }
%hdというのはshort型の変換文字です。
Borland C+;5.5のshort型は2バイト(-32768〜32767)、Int型とlong型は4バイトです。
ですので、long型の変数lの値(123456789)はshort型の変換文字%hdでは正確に出力されていません。
実数のほうはfloat型の変数もdouble型の変数も、%fでも%lfでも同じように出力されています。
%fも%lfもデフォルトでは小数点は6ケタ表示のようです。
実行例
printfのフォーマット文と変数の宣言の型の不一致で期待通りの出力(標準出力)が
得られない、うっかりミスの例
[ave.c]
#include <stdio.h>
int main(void){
int x[5]={2,4,3,9,5};
int i,sum,heikin,iave;
float ave, fheikin;
sum=0;
for (i=0; i<5; i++) {
sum=sum+x[i];
}
ave=sum/9.0;
heikin=sum/9.0;
printf("average %f\n",ave);
printf("average %d\n", ave);
printf("heikin %d\n", heikin);
printf("heikin %f\n", heikin);
printf("cast\n");
iave=(int)ave; /*castしてみる*/
fheikin=(float)heikin;
printf("average %d\n", iave);
printf("heikin %f\n", fheikin);
return 0;
}
以下の実施例を見ると
float型のaveを整数型の変換文字%dで変換した結果が、536870912とおかしな出力結果になっている。
int型のheikinを%fで変換した結果は、0.000000とこれも正しい出力結果になっていない。
最後にaveをint型に、heikinをfloat型にcastして出力してみている。
実施例
castについてはキャスト演算子とオートキャストをご参照下さい。