
C言語の基本|printfで表示を整える
表示の幅や桁数をそろえると、結果はぐっと読みやすくなる。printfのフィールド幅・フラグ・精度を使って、伝わる出力を作ろう。
printfは、文字や数値を画面に出すだけの関数ではありません。表示する幅や位置、桁数などを細かく指定する機能も備えています。
たとえば、次のような表示ができます。
- 数値を右側または左側へそろえる
- 異なる桁数の数値を同じ幅で並べる
- 空いている部分を0で埋める
- 正の数にもプラス記号を付ける
- 8進数や16進数の表記を分かりやすくする
- 小数点以下の桁数をそろえる
- 文字列の表示範囲を制限する
整形していない数値を縦に並べると、桁数が違うため比較しにくくなることがあります。
5
120
38
2400フィールド幅を指定して右側へそろえると、次のように見やすくなります。
5
120
38
2400このような表示は、学習中の動作確認、簡単な表、ログ、一覧などで役立ちます。
ここでは、printfの書式指定を構成するフィールド幅、フラグ、精度について、実行結果を見ながら確認していきましょう。
printfの書式指定の全体像
printfの書式指定には、これまで使用してきた%dや%fの間に、追加の情報を記述できます。
基本的な並びは次のとおりです。
%[フラグ][フィールド幅][.精度][修飾子]変換指定子それぞれの役割を整理すると、次のようになります。
| 部分 | 役割 | 例 |
|---|---|---|
| % | 書式指定の開始 | % |
| フラグ | 左詰めや0埋めなどを指定 | -、+、#、0 |
| フィールド幅 | 表示に確保する最小幅 | 5、8、10 |
| .精度 | 小数や文字列の表示範囲を指定 | .2、.4 |
| 修飾子 | データ型の長さなどを指定 | 今回は詳しく扱わない |
| 変換指定子 | 値の表示形式を決める | d、f、s、x |
たとえば、次の指定があります。
%5dこれは、int型の整数を最低5文字分の幅で右詰め表示する指定です。
%-5d-フラグが加わっているため、最低5文字分の幅で左詰め表示します。
%.2fdouble型の値を、小数点以下2桁で表示します。
%10.2f全体を最低10文字分の幅にし、小数点以下を2桁にします。
書式指定は記号が多く見えますが、左から順番に分ければ意味を読み取りやすくなります。
フィールド幅とは
フィールド幅は、値を表示するために確保する最小の横幅です。
整数を最低5文字分の幅で表示する場合は、次のように書きます。
printf("[%5d]\n", 10);実行結果は次のとおりです。
[ 10]値10は2桁です。フィールド幅として5文字分が指定されているため、不足する3文字分が空白になります。
角括弧はフィールド幅に含まれていません。空白の位置を分かりやすく確認するために表示しています。
指定がなければ右詰めになる
フィールド幅だけを指定した場合、値は右側へ寄せて表示されます。
printf("[%6d]\n", 58);
[ 58]58は2桁なので、左側に4文字分の空白が入ります。
| 内容 | 文字数 |
|---|---|
| 左側の空白 | 4 |
| 数値58 | 2 |
| 合計 | 6 |
数値を縦に並べる場合は、右詰めにすると桁の位置がそろいます。
printf("[%6d]\n", 5);
printf("[%6d]\n", 120);
printf("[%6d]\n", 2400);
[ 5]
[ 120]
[ 2400]フィールド幅は最小幅
フィールド幅は、表示できる最大文字数ではありません。最低限確保する幅です。
次の例では、幅3を指定しています。
printf("[%3d]\n", 10000);値10000は5桁なので、指定した幅3には収まりません。
実行結果は次のようになります。
[10000]値が途中で切り捨てられることはありません。必要な幅まで自動的に広がります。
指定した幅より短い値 → 不足分を空白で埋める
指定した幅より長い値 → 値をすべて表示する図1:フィールド幅5で整数を右詰めする仕組み

この図から分かること
%5dは、整数を最低5文字分の幅で表示する指定です。
値10は2桁なので、左側に3文字分の空白が入ります。フラグを指定していないため、数値は右詰めになります。
浮動小数点数のフィールド幅
浮動小数点数にもフィールド幅を指定できます。
printf("[%12f]\n", 123.456);%fで精度を省略すると、小数点以下が6桁表示されます。
123.456000この表示は、次の10文字で構成されています。
- 整数部分の123で3文字
- 小数点で1文字
- 小数部分の456000で6文字
合計10文字です。フィールド幅は12なので、左側に2文字分の空白が入ります。
[ 123.456000]フィールド幅には、数値の数字だけでなく、次のものも含まれます。
- 符号
- 小数点
- 小数部分
- 8進数や16進数の接頭辞
フラグで表示方法を変える
フラグは、値をどのように整えて表示するかを追加で指定する記号です。
今回扱う主なフラグは次の4つです。
| フラグ | 役割 | 書式指定例 | 表示例 |
|---|---|---|---|
| - | 左詰め | %-5d | [10 ] |
| + | 正の値にも符号を付ける | %+d | [+10] |
| # | 進数の表記を明示する | %#x | [0xa] |
| 0 | 空いている部分を0で埋める | %05d | [00010] |
-フラグで左詰めにする
通常のフィールド幅では、値は右詰めになります。
printf("[%5d]\n", 10);
[ 10]-フラグを付けると、左詰めになります。
printf("[%-5d]\n", 10);実行結果は次のとおりです。
[10 ]違いを並べると分かりやすくなります。
| 書式指定 | 詰める方向 | 表示結果 |
|---|---|---|
| %5d | 右詰め | [ 10] |
| %-5d | 左詰め | [10 ] |
文字列の項目名を左へそろえたいときにも利用できます。
printf("[%-10s]\n", "Sensor");
[Sensor ]+フラグで符号を表示する
通常、正の整数にはプラス記号が表示されません。
printf("[%d]\n", 10);
[10]+フラグを付けると、正の値にもプラス記号を付けられます。
printf("[%+d]\n", 10);
[+10]負の数には、通常どおりマイナス記号が表示されます。
printf("[%+d]\n", -10);
[-10]増減量や温度差など、正負を明確に示したい表示に便利です。
printf("前日からの変化: %+d\n", 5);
前日からの変化: +5#フラグで進数の表記を明示する
#フラグは、8進数や16進数を表示するときに、その表記形式を分かりやすくします。
16進数の場合は、0xまたは0Xが付きます。
unsigned int code = 42;
printf("%#x\n", code);
printf("%#X\n", code);
0x2a
0X2A8進数の場合は、先頭に0が付きます。
unsigned int code = 42;
printf("%#o\n", code);
052#フラグを使わない場合と比べると、進数を判断しやすくなります。
| 書式指定 | 表示結果 | 意味 |
|---|---|---|
| %o | 52 | 8進数 |
| %#o | 052 | 8進数の表記を明示 |
| %x | 2a | 小文字の16進数 |
| %#x | 0x2a | 小文字の16進数であることを明示 |
| %X | 2A | 大文字の16進数 |
| %#X | 0X2A | 大文字の16進数であることを明示 |
%o、%x、%Xには、unsigned int型の値を渡します。
0フラグで空きを0にする
0フラグをフィールド幅と組み合わせると、通常なら空白になる部分が0で埋められます。
printf("[%05d]\n", 10);実行結果は次のとおりです。
[00010]書式指定を分けると、次のようになります。
| 部分 | 意味 |
|---|---|
| % | 書式指定の開始 |
| 0 | 空きを0で埋める |
| 5 | 最低5文字分の幅 |
| d | int型の整数を10進数で表示 |
連番や管理番号など、桁数をそろえたい場合に利用できます。
printf("番号: %05d\n", 27);
番号: 00027左詰めと0埋めの違い
%-5dと%05dは、どちらも幅5を指定していますが、表示方法が異なります。
| 書式指定 | 表示方法 | 値10の表示 |
|---|---|---|
| %5d | 右詰め、空白埋め | [ 10] |
| %-5d | 左詰め、空白埋め | [10 ] |
| %05d | 右詰め、0埋め | [00010] |
-フラグは値を左側へ寄せます。0フラグは値を右側へ置き、左側を0で埋めます。
左詰めを指定した場合は、0ではなく空白で埋める形になります。
精度で小数点以下の桁数を指定する
浮動小数点数の精度は、小数点以下を何桁表示するかを指定します。
基本的な書き方は次のとおりです。
%.桁数f小数点以下2桁なら%.2fを使います。
printf("[%.2f]\n", 12345.678);実行結果は次のようになります。
[12345.68]小数点以下3桁目も考慮して、2桁に丸めて表示されます。
精度を変えると、同じ値でも見え方が変わります。
| 書式指定 | 表示結果 |
|---|---|
| %f | 12345.678000 |
| %.1f | 12345.7 |
| %.2f | 12345.68 |
| %.3f | 12345.678 |
| %.4f | 12345.6780 |
表示が丸められても、変数に保存されている値そのものは変わりません。
フィールド幅と精度を一緒に指定する
フィールド幅と精度は、同じ書式指定の中で組み合わせられます。
printf("[%10.2f]\n", 12345.678);%10.2fは、次のように読みます。
全体の最小幅 :10文字
小数点以下の桁数:2桁
表示形式 :通常の小数12345.678を小数点以下2桁にすると、12345.68になります。
12345.68これは8文字なので、幅10にするため左側に2文字分の空白が入ります。
[ 12345.68]図2:%10.2fを分解して読む

この図から分かること
%10.2fでは、10が表示全体の最小幅、2が小数点以下の桁数、fが通常の小数表記を表します。
まず精度に合わせて12345.68という表示を作り、その結果が幅10より短ければ、左側に空白が追加されます。
文字列にも精度を指定できる
%sにも精度を指定できます。
%.最大表示数s英字の文字列から先頭5文字を表示する場合は、次のように書きます。
printf("[%.5s]\n", "abcdefg");実行結果は次のとおりです。
[abcde]先頭から最大5文字分だけが表示され、それ以降は表示されません。
文字列の精度と浮動小数点数の精度では、意味が異なります。
| 書式指定 | 精度の意味 |
|---|---|
| %.2f | 小数点以下を2桁表示 |
| %.5s | 文字列の先頭から最大5単位分を表示 |
日本語文字列の精度指定には注意する
printfの%sに対する精度は、狭い文字列では最大バイト数として働きます。
UTF-8の日本語は、一般的に1文字が複数バイトで表現されます。そのため、次のような指定では、日本語を5文字表示できるとは限りません。
printf("%.5s\n", "プログラミング入門");指定した位置が日本語1文字を構成するバイト列の途中になると、文字が正しく表示されない可能性もあります。
動作を安定して確認する場合は、まず半角英数字の文字列を使うと分かりやすいでしょう。
printf("%.5s\n", "Programming");
Progr日本語の文字数とバイト数は同じとは限らない、という点を覚えておくと安心です。
フィールド幅・フラグ・精度を確認しよう
ここまでの指定を1つのプログラムにまとめて確認します。
センサー情報を整えて表示するプログラム
ファイル名:5_6_1.c
#include <stdio.h>
int main(void)
{
int sensor_count = 37;
unsigned int sensor_code = 37;
double accuracy = 87.6543;
/* フィールド幅を確認する */
printf("フィールド幅の例\n");
printf("[%-10s]\n", "Sensor");
printf("[%6d]\n", sensor_count);
printf("[%10.2f]\n", accuracy);
/* フラグを確認する */
printf("\nフラグの例\n");
printf("左詰め : [%-6d]\n", sensor_count);
printf("符号付き : [%+d]\n", sensor_count);
printf("16進数表記 : [%#x]\n", sensor_code);
printf("0埋め6桁 : [%06d]\n", sensor_count);
/* 精度を確認する */
printf("\n精度の例\n");
printf("小数2桁 : [%.2f]\n", accuracy);
printf("小数4桁 : [%.4f]\n", accuracy);
printf("英字5文字 : [%.5s]\n", "ControlSystem");
return 0;
}実行結果の例
フィールド幅の例
[Sensor ]
[ 37]
[ 87.65]
フラグの例
左詰め : [37 ]
符号付き : [+37]
16進数表記 : [0x25]
0埋め6桁 : [000037]
精度の例
小数2桁 : [87.65]
小数4桁 : [87.6543]
英字5文字 : [Contr]変数をデータ型に合わせて用意している
このプログラムでは、3種類の変数を用意しています。
int sensor_count = 37;
unsigned int sensor_code = 37;
double accuracy = 87.6543;それぞれの変数と書式指定の対応は次のとおりです。
| 変数 | データ型 | 使用する書式指定 |
|---|---|---|
| sensor_count | int | %d |
| sensor_code | unsigned int | %x |
| accuracy | double | %f |
16進数を表示する%xには、unsigned int型のsensor_codeを渡しています。
文字列を左詰めにしている
次のprintfでは、文字列Sensorを幅10で左詰めにしています。
printf("[%-10s]\n", "Sensor");Sensorは6文字なので、右側に4文字分の空白が入ります。
[Sensor ]文字列の項目名を縦に並べるときは、左詰めにすると読みやすくなります。
整数を幅6で右詰めにしている
次のprintfでは、sensor_countを幅6で表示しています。
printf("[%6d]\n", sensor_count);37は2桁なので、左側に4文字分の空白が入ります。
[ 37]フィールド幅だけを指定したため、右詰めです。
小数に幅と精度を指定している
次のprintfでは、全体幅を10、小数点以下を2桁にしています。
printf("[%10.2f]\n", accuracy);accuracyの値87.6543は、小数点以下2桁に丸められて87.65になります。
87.65は5文字なので、幅10に合わせて左側に5文字分の空白が入ります。
[ 87.65]#フラグで16進数だと分かるようにしている
次のprintfでは、%#xを使っています。
printf("16進数表記 : [%#x]\n", sensor_code);37を16進数で表すと25です。#フラグによって先頭に0xが追加されます。
0x25%xだけで表示した場合は25となります。%#xなら0x25となるため、16進数であることが伝わりやすくなります。
0フラグで6桁にそろえている
次のprintfでは、sensor_countを幅6で0埋めしています。
printf("0埋め6桁 : [%06d]\n", sensor_count);37は2桁なので、前に0が4つ入ります。
000037IDや連番のように、一定の桁数で表示したい場合に利用できます。
精度で小数の表示桁数を変えている
同じaccuracyを、異なる精度で表示しています。
printf("小数2桁 : [%.2f]\n", accuracy);
printf("小数4桁 : [%.4f]\n", accuracy);表示結果は次のとおりです。
87.65
87.6543書式指定を変更しても、accuracyに保存されている値そのものは変わりません。
英字文字列の先頭5文字を表示している
次のprintfでは、文字列ControlSystemの先頭から最大5文字を表示します。
printf("英字5文字 : [%.5s]\n", "ControlSystem");実行結果は次のとおりです。
Contr半角英字は1文字が1バイトなので、精度指定の動作を確認しやすくなります。
書式指定を選ぶ流れ
表示を整えるときは、次の順番で考えると分かりやすいでしょう。
- 表示する値のデータ型を確認する
- d、f、s、xなどの変換指定子を決める
- 必要な最小幅を決める
- 左詰めや0埋めなどのフラグを選ぶ
- 小数や文字列に必要な精度を指定する
- 実行結果を角括弧付きで確認する
たとえば、double型の値を幅8、小数点以下2桁で表示するなら、次のように組み立てます。
double型
↓
通常の小数表記なのでf
↓
幅8を追加
↓
小数点以下2桁を追加
↓
%8.2f図3:目的からprintfの書式指定を組み立てる

この図から分かること
書式指定は、完成形を丸暗記するだけでなく、データ型、フィールド幅、フラグ、精度の順に考えると組み立てやすくなります。
%8.2fなら、幅8と精度2を指定し、最後のfで通常の小数表記を選んでいることが分かります。
よくある間違いを確認しよう
printfの整形指定では、幅と精度の意味を混同しやすいため注意が必要です。
フィールド幅を最大幅だと思ってしまう
次の指定では、整数を最大3桁に制限するわけではありません。
printf("[%3d]\n", 10000);実行結果では10000がすべて表示されます。
[10000]フィールド幅は、最低限確保する横幅です。
0埋めと左詰めを混同する
%06dと%-6dは、どちらも幅6ですが、結果が異なります。
printf("[%06d]\n", 58);
printf("[%-6d]\n", 58);
[000058]
[58 ]| 書式指定 | 意味 |
|---|---|
| %06d | 右詰めし、左側を0で埋める |
| %-6d | 左詰めし、右側を空白で埋める |
幅と精度の位置を逆にする
幅はドットの前、精度はドットの後ろに書きます。
%8.2f| 部分 | 意味 |
|---|---|
| 8 | 全体の最小幅 |
| .2 | 小数点以下2桁 |
| f | 通常の小数表記 |
精度の意味が変換指定子によって変わる
同じ.数字でも、変換指定子によって意味が異なります。
%.2f浮動小数点数では、小数点以下2桁という意味です。
%.4s文字列では、先頭から最大4バイト分を表示する指定です。
変換指定子まで含めて意味を確認しましょう。
整形指定を使ってみよう
次の実行結果になるように、空欄へ書式指定を入れてみましょう。
右詰め6桁 : [ 73]
左詰め6桁 : [73 ]
符号付き表示 : [+73]
0埋め6桁 : [000073]
16進数を明示 : [0x49]
幅8・小数2桁 : [ 12.35]
小数点以下3桁 : [12.346]
先頭4文字 : [form]printfのフィールド幅・フラグ・精度を練習する問題
#include <stdio.h>
int main(void)
{
int value = 73;
unsigned int code = 73;
double measurement = 12.3456;
printf("右詰め6桁 : [ ➀ ]\n", value);
printf("左詰め6桁 : [ ➁ ]\n", value);
printf("符号付き表示 : [ ➂ ]\n", value);
printf("0埋め6桁 : [ ➃ ]\n", value);
printf("16進数を明示 : [ ➄ ]\n", code);
printf("幅8・小数2桁 : [ ➅ ]\n", measurement);
printf("小数点以下3桁 : [ ⓻ ]\n", measurement);
printf("先頭4文字 : [ ➇ ]\n", "format");
return 0;
}空欄には次の書式指定が入ります。
| 空欄 | 書式指定 | 役割 |
|---|---|---|
| ① | %6d | 幅6で右詰め |
| ② | %-6d | 幅6で左詰め |
| ③ | %+d | 正の値にもプラス記号を付ける |
| ④ | %06d | 幅6で0埋め |
| ⑤ | %#x | 16進数に0xを付ける |
| ⑥ | %8.2f | 幅8、小数点以下2桁 |
| ⑦ | %.3f | 小数点以下3桁 |
| ⑧ | %.4s | 文字列の先頭から最大4文字分 |
フィールド幅・フラグ・精度を使った解答プログラム
ファイル名:5_6_2.c
#include <stdio.h>
int main(void)
{
int value = 73;
unsigned int code = 73;
double measurement = 12.3456;
printf("右詰め6桁 : [%6d]\n", value);
printf("左詰め6桁 : [%-6d]\n", value);
printf("符号付き表示 : [%+d]\n", value);
printf("0埋め6桁 : [%06d]\n", value);
printf("16進数を明示 : [%#x]\n", code);
printf("幅8・小数2桁 : [%8.2f]\n", measurement);
printf("小数点以下3桁 : [%.3f]\n", measurement);
printf("先頭4文字 : [%.4s]\n", "format");
return 0;
}実行結果の例
右詰め6桁 : [ 73]
左詰め6桁 : [73 ]
符号付き表示 : [+73]
0埋め6桁 : [000073]
16進数を明示 : [0x49]
幅8・小数2桁 : [ 12.35]
小数点以下3桁 : [12.346]
先頭4文字 : [form]右詰めと左詰めを使い分けている
右詰めには%6dを使用します。
printf("右詰め6桁 : [%6d]\n", value);値73は2桁なので、左側に4文字分の空白が入ります。
左詰めには%-6dを使用します。
printf("左詰め6桁 : [%-6d]\n", value);値の右側に4文字分の空白が入ります。
正の値にプラス記号を付けている
+フラグを使うと、正の値にも符号を付けられます。
printf("符号付き表示 : [%+d]\n", value);73は正の値なので、+73と表示されます。
0埋めで6桁にそろえている
%06dでは、幅6で空いている部分を0にします。
printf("0埋め6桁 : [%06d]\n", value);73の前に0が4つ追加され、000073になります。
16進数に0xを付けている
%#xでは、値を小文字の16進数で表示し、先頭に0xを付けます。
printf("16進数を明示 : [%#x]\n", code);10進数の73は16進数では49なので、0x49と表示されます。
幅8と小数点以下2桁を同時に指定している
%8.2fでは、全体幅を8、小数点以下を2桁にします。
printf("幅8・小数2桁 : [%8.2f]\n", measurement);12.3456は12.35に丸められます。12.35は5文字なので、左側に3文字分の空白が入ります。
小数点以下3桁に丸めている
%.3fでは、小数点以下を3桁表示します。
printf("小数点以下3桁 : [%.3f]\n", measurement);12.3456は、表示時に12.346へ丸められます。変数measurementの中身が12.346に書き換えられるわけではありません。
英字文字列の先頭4文字を表示している
%.4sでは、文字列formatの先頭から最大4文字分を表示します。
printf("先頭4文字 : [%.4s]\n", "format");実行結果はformです。
まずは%5d、%-5d、%05d、%.2f、%8.2fを使って、さまざまな値を表示してみてください。角括弧を付けて実行すると、どこに空白が入ったのかを確認しやすくなります。
