C言語のprintf関数は、画面に文字や数値を表示するときに必ずと言ってよいほど使う関数です。
その中でも「書式指定子」は、数値や文字をどのような形で表示するかを決める、とても重要な仕組みです。
本記事では、C言語初心者の方にも分かりやすいように、printfの書式指定子を基本から具体的な使い方まで丁寧に解説していきます。
printfの書式指定子とは
printfとは
C言語のprintf関数は、標準出力(通常はコンソール画面)に文字列を表示するための関数です。
標準ライブラリstdio.hに定義されており、プログラムの動作確認やデバッグでも頻繁に使われます。
基本的な使い方は次のようになります。
#include <stdio.h>
int main(void) {
// 文字列をそのまま表示
printf("Hello, C language!\n");
// 整数を表示
int x = 10;
printf("x = %d\n", x); // %d が書式指定子
return 0;
}
上の例で、"x = %d\n" という文字列の中にある%dが書式指定子です。
この部分が、後ろに続く変数xの表示方法を指示しています。
書式指定子とは
書式指定子とは、printfの第1引数(フォーマット文字列)の中で、変数の値をどのように表示するかを指定する特別な記号です。
例えば次のように使います。
#include <stdio.h>
int main(void) {
int i = 123;
double d = 3.14;
char c = 'A';
printf("整数: %d\n", i); // 整数を10進数で表示
printf("小数: %f\n", d); // 小数を10進数で表示
printf("文字: %c\n", c); // 1文字を表示
return 0;
}
整数: 123
小数: 3.140000
文字: A
ポイントは、書式指定子の並びと、後ろに渡す引数の順番と型を必ず合わせることです。
型が合わないと、意図しない表示や実行時エラーの原因になります。
書式指定子の基本構造
書式指定子は、実は1文字の記号だけではなく、次のような構造を持っています。
%[フラグ][最小フィールド幅][.精度][長さ修飾子]変換指定子
初心者のうちはすべてを覚える必要はありませんが、形を知っておくとあとで理解しやすくなります。
代表的な要素を表にまとめます。
| 要素 | 例 | 役割 |
|---|---|---|
| % | % | 書式指定子の開始を表す |
| フラグ | 0, – | ゼロ埋めや左寄せなどの指定 |
| 最小フィールド幅 | 5, 10 | 表示に使う桁数(文字幅)を指定 |
| .精度 | .2, .3 | 小数点以下の桁数や文字列の最大文字数を指定 |
| 長さ修飾子 | l, h | long型など、より大きい(または小さい)型の指定 |
| 変換指定子 | d, f, s | 実際の型と表示形式を決める本体 |
初心者の方は、まず変換指定子(d, f, sなど)と、よく使う幅指定と精度指定から覚えるとよいです。
整数を表示するprintfの書式指定子
%dと%i
%dと%iは、どちらも符号付き10進整数を表示するための書式指定子です。
実用上はほぼ同じ意味で使えます。
#include <stdio.h>
int main(void) {
int a = 123;
int b = -45;
printf("a (%%d): %d\n", a);
printf("b (%%d): %d\n", b);
// %i でも同じように表示できる
printf("a (%%i): %i\n", a);
printf("b (%%i): %i\n", b);
return 0;
}
a (%d): 123
b (%d): -45
a (%i): 123
b (%i): -45
初心者のうちは%cst-red>%dを使うと覚えておけば十分です。
%u
%uは符号なし10進整数(unsigned int)を表示します。
負の数を扱わないカウンタやビット演算の結果などに使われます。
#include <stdio.h>
int main(void) {
unsigned int u = 4000000000U; // 符号なし整数
int s = -1;
printf("unsigned u = %u\n", u);
printf("int s as signed (%%d) = %d\n", s);
printf("int s as unsigned (%%u) = %u\n", s); // ビットパターンは同じ
return 0;
}
unsigned u = 4000000000
int s as signed (%d) = -1
int s as unsigned (%u) = 4294967295
同じ値でも、%dと%uでは解釈が変わることに注意してください。
%oと%x
%oと%xは、整数をそれぞれ8進数と16進数で表示します。
#include <stdio.h>
int main(void) {
unsigned int n = 255;
printf("10進数: %u\n", n); // 10進数
printf("8進数: %o\n", n); // 8進数
printf("16進数(小文字): %x\n", n); // 16進数(小文字)
printf("16進数(大文字): %X\n", n); // 16進数(大文字)
return 0;
}
10進数: 255
8進数: 377
16進数(小文字): ff
16進数(大文字): FF
アドレスやビットパターンの確認には、16進数表示の%xや%Xがよく使われます。
%c
%cは1文字(char型)を表示する書式指定子です。
整数としての文字コードを渡しても、その文字に変換して表示してくれます。
#include <stdio.h>
int main(void) {
char c1 = 'A';
int c2 = 66; // 'B' のASCIIコード
printf("c1 = %c\n", c1);
printf("c2 = %c\n", c2); // 整数66が 'B' として表示される
return 0;
}
c1 = A
c2 = B
文字として表示したいときは%cst-code>%c、文字コードの数値として表示したいときは%dを使います。
#include <stdio.h>
int main(void) {
char c = 'A';
printf("文字として: %c\n", c);
printf("文字コードとして: %d\n", c);
return 0;
}
文字として: A
文字コードとして: 65
整数の桁数指定とゼロ埋め
整数には表示する桁数(幅)を指定したり、足りない桁を0で埋めることができます。
代表的な指定方法は次の通りです。
| 書式 | 意味 |
|---|---|
%5d | 幅5桁で表示。足りない分は左側に空白を入れる |
%05d | 幅5桁で表示。足りない分は左側を0で埋める |
%-5d | 幅5桁で表示。左寄せで表示(右側に空白) |
コード例で確認してみます。
#include <stdio.h>
int main(void) {
int n = 42;
printf("そのまま表示 : %d\n", n);
printf("幅5桁(右寄せ) : %5d\n", n);
printf("幅5桁(左寄せ) : %-5d<-ここまで\n", n);
printf("幅5桁(ゼロ埋め) : %05d\n", n);
return 0;
}
そのまま表示 : 42
幅5桁(右寄せ) : 42
幅5桁(左寄せ) : 42 <-ここまで
幅5桁(ゼロ埋め) : 00042
ゼロ埋めは0フラグ、幅指定は数字、左寄せは-フラグと覚えるとよいです。
小数・文字・文字列のprintf書式指定子
%f
%fは実数(浮動小数点数)を10進数の小数として表示します。
floatやdoubleで使えます。
#include <stdio.h>
int main(void) {
double pi = 3.1415926535;
printf("pi = %f\n", pi); // デフォルトでは小数点以下6桁
return 0;
}
pi = 3.141593
デフォルトでは小数点以下6桁まで表示されます。
%eと%g
%eは指数表記(科学技術計算でよく使う形)で表示します。
#include <stdio.h>
int main(void) {
double x = 12345.6789;
printf("通常表記 %%f : %f\n", x);
printf("指数表記 %%e : %e\n", x);
return 0;
}
通常表記 %f : 12345.678900
指数表記 %e : 1.234568e+04
%gは、値に応じて%eか%fのどちらか短い方を自動で選んで表示してくれます。
とりあえず「見やすく表示したい」ときに便利です。
#include <stdio.h>
int main(void) {
double a = 12345.6789;
double b = 0.000012345;
printf("a を %%g で表示: %g\n", a);
printf("b を %%g で表示: %g\n", b);
return 0;
}
a を %g で表示: 12345.7
b を %g で表示: 1.2345e-05
小数点以下の桁数指定
実数では小数点以下の桁数を.nの形式で指定できます。
%.2fのように書きます。
#include <stdio.h>
int main(void) {
double pi = 3.1415926535;
printf("デフォルト(6桁) : %f\n", pi);
printf("小数点以下2桁 : %.2f\n", pi);
printf("小数点以下4桁 : %.4f\n", pi);
printf("幅8・小数点以下2桁 : %8.2f\n", pi);
printf("幅8・小数点以下2桁(左寄せ): %-8.2f<-ここまで\n", pi);
return 0;
}
デフォルト(6桁) : 3.141593
小数点以下2桁 : 3.14
小数点以下4桁 : 3.1416
幅8・小数点以下2桁 : 3.14
幅8・小数点以下2桁(左寄せ): 3.14 <-ここまで
幅と精度は%8.2fのように、幅.精度の順で指定します。
%s
%sは文字列(char配列・文字列リテラル)を表示する書式指定子です。
#include <stdio.h>
int main(void) {
char name[] = "Taro";
char *lang = "C language";
printf("name = %s\n", name);
printf("language = %s\n", lang);
return 0;
}
name = Taro
language = C language
注意点として、%sにはchar *(先頭アドレス)を渡す必要があることを覚えておきましょう。
配列名や文字列リテラルは自動的にchar *として扱われます。
文字列の幅指定と左寄せ
文字列も整数や小数と同じように、表示幅の指定や左寄せができます。
#include <stdio.h>
int main(void) {
char str[] = "ABC";
printf("そのまま : '%s'\n", str);
printf("幅5(右寄せ) : '%5s'\n", str);
printf("幅5(左寄せ) : '%-5s'\n", str);
printf("最大文字数2文字: '%.2s'\n", str); // 先頭2文字だけ
printf("幅5かつ最大2文字: '%5.2s'\n", str); // 幅5で、最大2文字
return 0;
}
そのまま : 'ABC'
幅5(右寄せ) : ' ABC'
幅5(左寄せ) : 'ABC '
最大文字数2文字: 'AB'
幅5かつ最大2文字: ' AB'
%.2sのように精度を指定すると、文字列の最大出力長を制限できます。
長い文字列を切り詰めて表示したいときに役立ちます。
便利なprintfの書式指定子と実践テクニック
%p
%pはポインタ(アドレス)を表示するための書式指定子です。
デバッグで変数のアドレスを確認したいときによく使います。
#include <stdio.h>
int main(void) {
int x = 10;
int *p = &x; // xのアドレスを格納
printf("x の値 : %d\n", x);
printf("x のアドレス: %p\n", (void *)&x);
printf("p の値(=xのアドレス): %p\n", (void *)p);
return 0;
}
x の値 : 10
x のアドレス: 0x7ffdxxxxxxxx
p の値(=xのアドレス): 0x7ffdxxxxxxxx
%pに渡すときは(void *)にキャストするのが推奨されています。
コンパイラの警告を避けるためにも、ポインタを表示するときは%pと(void *)という組み合わせを覚えておくと安心です。
%%
%%はパーセント記号%cst-code>%自身を表示するための書式指定子です。
%は書式指定子の開始記号なので、printf("50%");のように書くとエラーになります。
#include <stdio.h>
int main(void) {
int progress = 80;
// % を表示したいときは %% と書く
printf("進捗: %d%% 完了しました。\n", progress);
return 0;
}
進捗: 80% 完了しました。
パーセント記号を表示したいときは、必ず%%と2つ続けて書くと覚えてください。
エスケープシーケンス
printfでは、改行やタブなどの特殊な制御文字を、エスケープシーケンスという形で指定します。
主なエスケープシーケンスを表にまとめます。
| エスケープシーケンス | 意味 |
|---|---|
\n | 改行 |
\t | 水平タブ |
\ | バックスラッシュ() |
" | ダブルクォート(“) |
' | シングルクォート(‘) |
実際の動きを確認してみます。
#include <stdio.h>
int main(void) {
printf("1行目\n2行目\n");
printf("A\tB\tC\n");
printf("バックスラッシュ: \\\n");
printf("ダブルクォート: \"\n");
printf("シングルクォート: '\n");
return 0;
}
1行目
2行目
A B C
バックスラッシュ: \
ダブルクォート: "
シングルクォート: '
エスケープシーケンスは\から始まる2文字以上の特別な記法で、文字列リテラルの中でしか使えないことにも注意してください。
初心者が最初に覚えたい書式指定子ベスト10
最後に、C言語初心者がまず覚えておきたい書式指定子ベスト10をまとめておきます。
これらを使いこなせれば、基本的な入出力はほとんど困らなくなります。
| 順位 | 書式指定子 | 主な用途・説明 |
|---|---|---|
| 1 | %d | 符号付き10進整数の表示(int) |
| 2 | %f | 実数(浮動小数点)の表示(double/float) |
| 3 | %s | 文字列の表示(char配列・char *) |
| 4 | %c | 1文字(char)の表示 |
| 5 | %u | 符号なし10進整数(unsigned int) |
| 6 | %x | 16進数整数の表示(デバッグで便利) |
| 7 | %p | ポインタ(アドレス)の表示 |
| 8 | %% | パーセント記号%を表示 |
| 9 | %8d | 幅指定つき整数表示(右寄せ・桁をそろえる) |
| 10 | %.2f | 小数点以下の桁数を指定した実数表示(小数2桁など) |
実際にこれらをまとめて使ったサンプルを見てみましょう。
#include <stdio.h>
int main(void) {
int id = 7;
int score = 95;
double avg = 89.456;
char grade = 'A';
char name[] = "Taro";
printf("ID: %03d\n", id); // 3桁ゼロ埋め
printf("名前: %s さん\n", name); // 文字列
printf("成績: %c (得点: %d 点)\n", grade, score);
printf("平均点: %.1f 点\n", avg); // 小数1桁
printf("平均点(詳細): %.3f 点\n", avg); // 小数3桁
return 0;
}
ID: 007
名前: Taro さん
成績: A (得点: 95 点)
平均点: 89.5 点
平均点(詳細): 89.456 点
このレベルの書式指定子を自由に組み合わせられるようになると、出力の見栄えやデバッグ効率がぐっと上がります。
まとめ
本記事では、C言語初心者の方向けにprintfの書式指定子について、基本から少し実践的なテクニックまで解説しました。
まず、printfとは何か、その中で書式指定子が「変数をどう表示するか」を決める大切な役割を持っていることを確認しました。
書式指定子の基本構造(%[フラグ][幅][.精度][長さ]変換指定子)を知っておくことで、幅指定や精度指定など少し高度な使い方も理解しやすくなります。
次に、整数用の%d, %u, %x, %cなどを使って、符号の有無や基数(10進・16進)の違い、桁数指定やゼロ埋めの方法を見てきました。
さらに、実数用の%f, %e, %gと、小数点以下の桁数指定、文字列用の%sとその幅指定や左寄せについても具体的なサンプルで確認しました。
最後に、ポインタ表示の%pやパーセント記号を出す%%、エスケープシーケンスなど、デバッグや実用的な出力で欠かせないテクニックも紹介し、初心者がまず押さえておきたい書式指定子ベスト10を一覧で整理しました。
最初は%d・%f・%sの3つに慣れ、それから幅指定や精度指定を少しずつ試していくと、負担を感じずにステップアップしやすくなります。
実際に自分でprintfをたくさん書いて、表示の違いを体験しながら覚えていってください。
