C言語入門講座

トップ>コンテンツ>C言語>3.printfを使いこなそう

 当講座はメールマガジン「Cプロダクション」の2000年5月10日から2002年7月31日までの記事を再編集したものです。

3.printfを使いこなそう

3-1. 書式付フォーマット
3-2. 8進数、16進数として表示するには?
3-3. 実数の変換指定子
3-4. 汎用的な変換指定子
3-5. 文字用の変換指定子
3-6. その他の変換指定子
3-7. フィールド幅
3-8. 精度
3-9. フラグ
3-10. 型の補足
3-11. まとめ

3-1. 書式付フォーマット

◆書式付フォーマット1


それでは、第一回目は変換指定子から

−変換指定子?

えーっと、printf()文中にある%dなど最初にパーセントがついたものです。

printf("var i = %d ",i);
               ~~~~
まずは、%dから説明しましょう。

◇%d

%dは変数(定数)の値を10進整数として出力します。

printf("%d\n",25);
printf("%d\n",-3);

出力:
25
-3

文字定数ならその文字コードが出力されます。

printf("%d\n",'A');

出力:
65

注意として整数型のみで使用してください。実数型の定数で%dを使っても正しい
値を出力できません。


◇%i

%iは%dと同じ働きをします。


◇%u

%uは符号なしの10進整数として表示します。

printf("%d\n",25);
printf("%d\n",-3);

出力:(intが16bitの場合)
25
65533

出力:(intが32bitの場合)
25
4294967293

3-2. 8進数、16進数として表示するには?

◆8進数、16進数として表示するには?

 整数を8進、16進数として表示する変換指定子です。
まずは、

◇%o

%oは整数を符号なしの8進数として表示するための変換指定子です。

#include<stdio.h>
main()
{
    printf("%o\n",32);
}

結果:
40

と表示されます。(8進数の40は10進数の32です)


◇%x

今度は整数を16進数として表示する変換指定子です。

#include<stdio.h>

main()
{
    printf("%x",234);
}

結果:
ea

と表示されます。

16進数の表示のとき10〜15の数はアルファベットのa〜fを用いて表示しま
す。

また、16進数表示の変換指定子にはもうひとつあります。


◇%X

今度はエックスが大文字になっています。
これは、16進数を表示するときにつかうアルファベットに大文字を使うことを
意味します。

#include<stdio.h>

main()
{
    printf("%X",234);
}

結果:
EA

このように、a〜fがA〜Fとなります。

3-3. 実数の変換指定子

◆実数の変換指定子

◇%f

%fはdouble型の数値を固定少数の形で表現します。

#include<stdio.h>
main()
{
    printf("%f\n",123.456);
}

結果:
123.456000

と表示されます。
次に、表示させる値をちょっと変えてみます。

#include<stdio.h>
main()
{
    printf("%f\n",0.001234);
}

結果:
0.001234

数値が1未満の場合でも必ず整数部は1桁表示するようになっています。


◇%e

%eははdouble型の数値を浮動少数の形で表現します。つまり指数形式になりま
す。

#include<stdio.h>
main()
{
    printf("%e\n",123.456);
    printf("%e\n",0.001234);
}

結果:
1.234560e+002
1.234000e-003

と表示されました。
それぞれ
e+002は10の2乗
e-003は10の−3乗を意味します。


◇%E

これは%eの場合、eと表示されている部分がEとなって表示されます。

#include<stdio.h>
main()
{
    printf("%E\n",123.456);
    printf("%E\n",0.001234);
}

結果:
1.234560E+002
1.234000E-003

となります。

3-4. 汎用的な変換指定子

◆汎用的な変換指定子

◇%g

その変換指定子は%gです。例として以下にプログラムを示します。

#include<stdio.h>

main()
{
    printf("%g\n",123.456);
    printf("%g\n",0.00001);
    printf("%g\n",12345.67890);
    printf("%g\n",10.000);

}

結果:
123.456
1e-005
1.23457e+006
10

1番目の結果は%fと同じような表示になりました。
2番目は数値が十分小さいため%eと同じ指数表示になりました。
3番目は整数部小数部ともに桁が多いため指数表示になりました。
4番目は小数部が0のため表示は整数になりました。

ここで気をつけなければならないのは整数表示できるからといって最初から整
数型の変数に%gを使用すると誤った値を返しますのであくまで実数型で使用し
てください。


◇%G

%GについてもeがEに変わる点以外はまったく同じです。

#include<stdio.h>

main()
{
    printf("%G\n",123.456);
    printf("%G\n",0.00001);
    printf("%G\n",12345.67890);
    printf("%G\n",10.000);

}

結果:
123.456
1E-005
1.23457E+006
10

となります。注意点についても同様です。

3-5. 文字用の変換指定子

◆文字用の変換指定子

そもそも、printf()で文字を出力するとき

printf("文字列");

でできるはずですが...しかしこれではあらかじめ決められた文字列しか表示で
きませんね。

というわけで、変換指定子には文字型や文字列型が用意されています。
(そういえばダブルクォーテーションで囲んだものはと文字列定数と呼ぶらしい)


◇%c

%cは文字型の変換指定子で、文字一文字の表示を行います。
もちろん、エスケープシーケンスも使用可能です。

#include<stdio.h>

main()
{
    printf("%c\n",'A');
}

結果:
A

とでます。次のようにするとどうでしょう。

#include<stdio.h>

main()
{
    printf("%c\n",90);
}

結果:
Z

整数値が文字コードとして扱われ、それに対応する文字が表示されました


◇%s

今度は文字列の表示を行う変換指定子です。

使い方は以下のようになります。

#include<stdio.h>

main()
{
    printf("%s\n","文字列");
}

これはちょうど、

#include<stdio.h>

main()
{
    printf("文字列\n");
}

と同じになり、

結果:
文字列

と表示されます。

これを配列を用いて表示するときは
#include<stdio.h>

main()
{
    char str[]="文字列";
    printf("%s\n",str);
}

のようにします。
この場合なぜstrなのかはそのうちやります。(ポインタと一緒に...)

3-6. その他の変換指定子

◆変換指定子(その他)

◇%%

これはprintf()の文字列中に%を表示するものです。前にも似たようなものがあ
りましたね(\\で\を表示する)

#include<stdio.h>
main()
{
    printf("%%\n");
}

結果:
%


◇%p

次に%pこれは引数をアドレスとして表示します。(もちろん16進数)
よって引数にはvoidのポインタを使用します。要するに対象となる変数の型は
何でもOKと言う意味です。

といっても普通に引数を渡せば数値を大文字16進数にしてあまった桁は0で
埋めて表示するだけです。(%Xにあまった桁を0で埋めるのと同じ)

だから、

#include<stdio.h>

main()
{
    printf("%p\n",255);
}

結果:
000000FF

と表示されますが、せっかくアドレス用の変換指定子なので、ある変数のアド
レスを表示させましょう。

#include<stdio.h>
main()
{
    int a=0;
    printf("%p\n",&a);
}

結果:
0065FDF4

と表示されました。なおこの値は通常毎回変わります。
プログラムを実行すると適当にメモリが空いた区間に変数用の領域を確保する
ので、そのときのアドレスが毎回変わるためです。

ちなみに&aは変数aのアドレスです。注意点として変数は必ず初期化してくださ
い。さもないとメモリに確保されません。

◇%n

%nは引数に整数へのポインタを使いまして、バッファ中に格納されている文字
の数を数えて指定した整数変数へ値を格納します。よって画面に出力されませ
ん。

このへんかなり説明がややこしいし基本的にポインタを使うのでプログラム見
ただけで理解するほうが大変かも。

ということで特別に番号つきでマガジン上でステップインしながらやりましょ
う。

#include<stdio.h>
main()
{
    int count=0;                              /* (1) */
    printf("C-Production%nNo.030\n",&count);  /* (2) */
    printf("%d\n",count);                     /* (3) */
}

結果:
C-ProductionNo.030
12

と出ました。それではステップインします。

まず(1)では変数の初期化を行っています。宣言だけで初期化しなかったら
メモリを確保してもらえないからですね。

(2)で%nを使用しています。ここで大事なのは文字のカウントの対象となる部分
がどこからどこまでかになります。
それは%nのある文字列の最初から%nの手前までです。
つまりプログラムではC-Productionになります。
この範囲では12文字あるので引数であるポインタを通して変数countに12を代
入しています。

(3)最後に変数countを10進数表示したら12と表示されました。

と一連の動作はこのようになります。

昨日の%pと一緒にポインタも用意してサンプルプログラムを組んでみます。

#include<stdio.h>
main()
{
    int count=0;
    int *pointer;
    pointer=&count;

    printf("C-Production No.030%n\n",pointer);
    printf("上記の文字列の文字数は %d 文字です。\n",count);
    printf("ちなみに、変数countのアドレスは %p 番地です。\n",pointer);
}

実行結果:
C-Production No.030
上記の文字列の文字数は 19 文字です。
ちなみに、変数countのアドレスは 0065FDF4 番地です。

と表示されました。スペースもちゃんとカウントされていますね。
また全角文字の場合は全角1文字を2文字としてカウントします。

3-7. フィールド幅

◆フィールド幅

−フィールド幅とは?

まず、今までどおりの方法で3×3の行列を表示してみます。

#include<stdio.h>
main()
{
    int i,j;
    int matrix[3][3]={{12,34,46},
                      {643,2,45},
                      {435,34,2545}};
    for(i=0;i<3;i++){
        for(j=0;j<3;j++)printf("%d ",matrix[i][j]);
        printf("\n");
        }
}

結果:
12 34 46
643 2 45
435 34 2545

これでは、各要素が揃ってないので見づらいですね。

スペースで揃えればこの場合何とかなりますが、配列の数値が未知数だとうま
くできません。

そこで必要なのがフィールド幅の指定です。

#include<stdio.h>
main()
{
    int i,j;
    int matrix[3][3]={{12,34,46},
                      {643,2,45},
                      {435,34,2545}};
    for(i=0;i<3;i++){
        for(j=0;j<3;j++)printf("%4d ",matrix[i][j]);
        printf("\n");
        }
}

 % と d の間に 4 を入力しました。これがフィールド幅の指定で、これを実行
すると、

結果:
  12   34   46
 643    2   45
 435   34 2545

となり、きれいに表示されました。この 4 の意味は『4桁の幅で表示』になり
ます。もし、このときに数値が4桁を超えたばあいはその数値のみそのまま表
示されます。

#include<stdio.h>
main()
{
    int i,j;
    int matrix[3][3]={{12,34,46},
                      {687643,2,45},
                      {435,34,2545}};
    for(i=0;i<3;i++){
        for(j=0;j<3;j++)printf("%4d ",matrix[i][j]);
        printf("\n");
        }
}

結果:
  12   34   46
687643    2   45
 435   34 2545

2行目のはじめの数値が6桁なのでそれ以降右側はズレてしまいました。

 今から整数型以外でのフィールド幅について確認も含めてやってみます。

◇%f の場合

#include<stdio.h>
main()
{
    int i,j;
    double matrix[3][3]={{12.33,34.2,46.456},
                      {687643.44,2.3,45.1},
                      {435.4,3.4,25.45}};
    for(i=0;i<3;i++){
        for(j=0;j<3;j++)printf("%15f ",matrix[i][j]);
        printf("\n");
        }
}

結果:
      12.330000       34.200000       46.456000
  687643.440000        2.300000       45.100000
     435.400000        3.400000       25.450000


◇%e の場合

#include<stdio.h>
main()
{
    int i,j;
    double matrix[3][3]={{12.33,34.2,46.456},
                      {687643.44,2.3,45.1},
                      {435.4,3.4,25.45}};
    for(i=0;i<3;i++){
        for(j=0;j<3;j++)printf("%15e ",matrix[i][j]);
        printf("\n");
        }
}

結果:
  1.233000e+001   3.420000e+001   4.645600e+001
  6.876434e+005   2.300000e+000   4.510000e+001
  4.354000e+002   3.400000e+000   2.545000e+001


◇%g の場合

#include<stdio.h>
main()
{
    int i,j;
    double matrix[3][3]={{12.33,34.2,46.456},
                      {687643.44,2.3,45.1},
                      {435.4,3.4,25.45}};
    for(i=0;i<3;i++){
        for(j=0;j<3;j++)printf("%15g ",matrix[i][j]);
        printf("\n");
        }
}

結果:
          12.33            34.2          46.456
         687643             2.3            45.1
          435.4             3.4           25.45


◇%s の場合

#include<stdio.h>
main()
{
    int i;
    char str[3][12]={"おはよう","こんにちは","こんばんは"};
    for(i=0;i<3;i++){
        printf("%15s ",str[i]);
        printf("\n");
        }
}

結果:
       おはよう
     こんにちは
     こんばんは

となり変換型に関係なく15文字分の領域を確保して右端をそろえた状態で出力
されます。


◇アスタリスクを使ったフィールド幅指定

早速ですが、例を下に示します。
#include<stdio.h>
main()
{
    int i;
    for(i=1;i<10;i++)printf("%*d",2,i);
 }

結果:
 1 2 3 4 5 6 7 8 9

このようにアスタリスクを使うとそのアスタリスクに対応する整数型の定数
(変数)をフィールド幅として定義します。

これは、フィールド幅を変数の値によって決めたいときに有効な方法です。

ですから、以下のような事がアスタリスクによってできます。

#include<stdio.h>
main()
{
    int i;
    for(i=1;i<10;i++)printf("%*d\n",i,i);
 }

結果:
1
 2
  3
   4
    5
     6
      7
       8
        9

3-8. 精度

◆精度

 次は精度の設定です。ここでは、精度の意味について少し述べます。

たとえば、

3.1415926535

という数があります。(...て円周率じゃん!)

しかし、ここまで表示する必要がないので小数点以下第2までにします。

このときに精度を2と設定してあげると、(%fの場合)

3.14

になります。


◆整数型の場合

まず、整数型の精度のデフォルトは1です。整数型の場合表示する桁数の最小
を設定します。なのでデフォルトの1の場合最低1桁の表示がなされるという
ことになります。(0でも0と表示されるわけ)

1230
230
30
0

つまり精度を0にすると、数値が0のとき表示されなくなってしまいます。

1230
230
30


逆に精度を大きくしたときは余った桁を0で埋めます。
(精度4の時)

1230
0230
0030
0000

printf()での設定はどうなるかというと、

% のあと.(数字)で設定します。
もちろんフィールド幅と併用できます。

#include<stdio.h>
main()
{
    printf("%.3d\n",12);  /* 精度3 */
    printf("%1.3d\n",23); /* フィールド幅の併用可 */
    printf("%.0d\n",0);   /* 精度0で値0だと表示されない */
}

結果:
012
023


となりました。

◆実数型の場合

◇f,e,E

精度と言うには実数型の場合が一番ふさわしいと思います。
No.033に出てきた円周率の例を使ってやってみようと思います。

円周率=3.1415926535...

これを精度を指定しないままで表示すると

#include<stdio.h>
main()
{
    printf("%f\n",3.1415926535);
    printf("%e\n",3.1415926535);
}

結果:

3.141593
3.141593e+000

と表示されます。

ここでの精度は小数点以下の桁数の指定になります。
そして、デフォルトは6であり、それ以下は四捨五入されます。

今度は円周率を100倍して表示してみました。

#include<stdio.h>
main()
{
    printf("%f\n",3.1415926535*100);
    printf("%e\n",3.1415926535*100);
}

結果:

314.159265
3.141593e+002

あくまで、小数点以下第6位までの表示になっています。

それでは、このデフォルトの値を変えて0にしたらどうでしょうか?

#include<stdio.h>
main()
{
    printf("%.0f\n",3.1415926535);
    printf("%.0e\n",3.1415926535);
}

結果:
3
3e+000

となり、小数点まで省略されてしまいました。


◇g,G

g、Gの場合の精度は有効桁数になります。

#include<stdio.h>
main()
{
    printf("%g.3\n",1.2345);
    printf("%g.3\n",0.12345);
    printf("%g.3\n",0.0000012345);
}

結果:
1.23
0.123
1.23e-006

どれも有効数字3桁になっています。


◇s

 文字列の場合は出力する最大文字数になります

#include<stdio.h>
main()
{
    printf("%.10s\n","文字列の場合は");
}

結果:

文字列の場

となります。


◇アスタリスクを使う

精度でもアスタリスクが使えます。

#include<stdio.h>
main()
{
    printf("%.*s\n",10,"文字列の場合は");
}

結果:

文字列の場

このようにアスタリスクに対応する整数型のデータを精度として扱います。

フィールド幅との併用もできます。

#include<stdio.h>
main()
{
    printf("%*.*s\n",15,10,"文字列の場合は");
}

結果:

     文字列の場

ここでは15がフィールド幅10が精度として対応しています。


3-9. フラグ

◆フラグ

フラグについて:
 フラグはフィールド内での表示を設定します。

◇+と−と空白

+(プラス)

プログラム:
#include<stdio.h>
main()
{
    printf("%+3d\n",333);
}

結果:
+333

この+は符号を常に出力するフラグです。もちろん−も出力されます。

−(マイナス)

プログラム:
#include<stdio.h>
main()
{
    printf("%-10d\n",333);
    printf("%+10d\n",333);
}

結果:
333
      +333

−はフィールド内を左から出力するフラグです。もちろんフィールド幅の値を
出力文字数よりも多くしないと意味がありません。

(空白)

空白はあらかじめ符号の部分のスペースを確保してくれます。+と一緒に指定
されたときは、+が優先され(空白)は無効になります。

プログラム:
#include<stdio.h>
main()
{
    printf("% d\n",333);
    printf("% d\n",-333);
}

結果:
 333
-333

◇#

#は変換指定子によって働きが違うので、1つ1つ説明します。

o   :出力される8進数の頭に0を付加します。(0以外)
x,X :出力される16進数の頭に0x,0Xを付加します。(0以外)
f,e,g,F,E,G:常に小数点を表示
g,G:小数点以下の0を出力

プログラム:
#include<stdio.h>
main()
{
    printf("%#o\n",333);
    printf("%#x\n",333);
    printf("%#.0f\n",333.3);
    printf("%#.0e\n",333.3);
    printf("%#.0g\n",333.3);
    printf("%#g\n",333.3);
}

結果:
0515
0x14d
333.
3.e+002
3.e+002
333.300


◇0

0は出力文字の左側の空白を0で埋めます。ただし−が指定されていると無視
されてしまいます。また整数型で精度が指定されているときも無視されます。
もちろんフィールド幅は指定しないと意味がありません。

プログラム:
#include<stdio.h>
main()
{
    printf("%010d\n",333);
    printf("%10d\n",333);
}

結果:
0000000333
       333

3-10. 型の補足

整数型の場合

h : short int
l : long int

実数型の場合

L : long double

表示しようとする変数(定数)がこれらの型であるときその型に合わせて指定し
てやると、正確に表示されます。

3-11. まとめ

printf()の変換指定の書式をまとめると、

%[flag][field width][precision][type][conversion specifier]

%[フラグ][フィールド幅][精度][型の補足][変換指定子]

となります。

Copyright© 2000-2009 C-Production All Rights Reserved.