2.

printf 数値書式完全ガイド — %d/%f/%e の使い方

編集
この記事の要点
  • %d 整数 / %f 浮動小数 / %e 指数 / %x 16進 / %o 8進 — 基本変換指定
  • 幅指定 %5d = 最低 5 桁、左寄せ %-5d0 埋め %05d
  • 精度 %.2f = 小数点以下 2 桁、%10.2f = 幅 10・精度 2
  • 符号付き %+d でプラスも表示、long long%lldsize_t%zu
  • 書式と引数の不一致は未定義動作。C++ で cout / Java System.out.printf / Python print(f"...") も類似書式
  • C コンパイラの -Wformat 警告で書式不一致を検知 (gcc/clang デフォルト有効)

printf の基本

C 言語の標準ライブラリ関数 printf は、書式文字列に基づいて値を整形して標準出力に書き出します。書式は % から始まる変換指定子で表します。

#include 

int main(void) {
    int x = 42;
    double pi = 3.14159;

    printf("%d\n", x);        // 42
    printf("%f\n", pi);        // 3.141590
    printf("x=%d, pi=%.2f\n", x, pi);  // x=42, pi=3.14
    return 0;
}

主要な変換指定子

指定子意味例 (値)出力
%d / %i10 進整数 (signed int)4242
%u10 進整数 (unsigned int)4242
%x / %X16 進整数 (小文字 / 大文字)255ff / FF
%o8 進整数810
%f / %F10 進浮動小数3.143.140000
%e / %E指数表記123456.7891.234568e+05
%g / %G%e / %f の短い方を自動選択0.00010.0001
%c1 文字 (int を char として)65A
%s文字列 (char*)"hi"hi
%pポインタ&x0x7ffe1234abcd
%%パーセント記号自体%

幅・寄せ・0 埋め

#include 

int main(void) {
    int x = 42;

    printf("[%d]\n",   x);   // [42]
    printf("[%5d]\n",  x);   // [   42]     幅 5 (右寄せ)
    printf("[%-5d]\n", x);   // [42   ]     左寄せ
    printf("[%05d]\n", x);   // [00042]     0 埋め

    // 浮動小数
    double pi = 3.14159;
    printf("[%f]\n",     pi); // [3.141590]
    printf("[%.2f]\n",   pi); // [3.14]      小数点以下 2 桁
    printf("[%10.2f]\n", pi); // [      3.14] 幅 10
    printf("[%-10.2f]\n",pi); // [3.14      ] 左寄せ
    return 0;
}

符号 / 基数プレフィックス

printf("[%+d]\n", 42);   // [+42]    正でも符号
printf("[%+d]\n", -42);  // [-42]
printf("[% d]\n", 42);   // [ 42]    空白で符号位置確保

// 基数プレフィックス: # フラグ
printf("[%#x]\n", 255);  // [0xff]   0x プレフィックス
printf("[%#o]\n", 8);    // [010]    0 プレフィックス

長さ修飾子 (型サイズ指定)

修飾子対象型
%hdshortprintf("%hd", (short)42);
%ldlongprintf("%ld", 42L);
%lldlong longprintf("%lld", 42LL);
%zd / %zusize_t / ssize_tprintf("%zu", sizeof(int));
%jdintmax_t
%lfdouble (scanf 必須、printf では %f と同等)
%Lflong double

書式不一致は未定義動作

// ✗ 危険: long long を %d で受ける → 未定義動作 (32bit/64bit で挙動が異なる)
long long big = 1234567890123LL;
printf("%d\n", big);   // ← 警告: format expects 'int' but argument has type 'long long'

// ✓ 正しい
printf("%lld\n", big);

// gcc/clang で警告を出すフラグ
// gcc -Wformat -Wformat-signedness -o app app.c

printf は可変長引数なので型チェックが弱く、書式と引数の型が一致しないとクラッシュ / 出力ゴミ / セキュリティホールになります (Format String Attack)。-Wall -Wformat は必須。

引数番号指定 (POSIX 拡張)

// POSIX printf は引数番号 %n$ で位置指定可
printf("%2$s, %1$s\n", "World", "Hello");
// → Hello, World

// 国際化対応で語順が変わる文に便利

他言語の対応書式

Java

System.out.printf("%-10s %5d %8.2f%n", "Alice", 42, 3.14);
// "Alice          42     3.14\n"

// String.format で文字列化
String s = String.format("%05d", 42);  // "00042"

C++

#include 
#include 
#include 
#include   // C++20

// C 由来 printf もそのまま使える
printf("%5d\n", 42);

// iomanip で書式設定
std::cout << std::setw(5) << std::setfill('0') << 42 << "\n";

// C++20 std::format
std::cout << std::format("{:05d}\n", 42);  // 00042
std::cout << std::format("{:.2f}\n", 3.14159);  // 3.14

Python

# 旧 % 書式 (C printf 直系)
print("%5d" % 42)         # "   42"
print("%-5d %.2f" % (42, 3.14))

# str.format
print("{:5d} {:.2f}".format(42, 3.14))

# f-string (Python 3.6+) - 推奨
x = 42
pi = 3.14159
print(f"{x:5d} {pi:.2f}")    # "   42 3.14"
print(f"{x:05d}")            # "00042"

FAQ

Q: %d%i の違いは?
A: printf ではどちらも同じ。scanf では %i0x / 0 プレフィックスを自動認識して基数判定する違いがあります。

Q: 改行コードは?
A: 文字列内に \n を書く必要があります。printf は puts と違って自動で改行しません。

Q: バッファに書き出したい
A: sprintf / より安全な snprintf(buf, sizeof buf, ...) を使います。

Q: float を %d で出すと?
A: 未定義動作。整数として解釈されて意味不明な値になります。必ず (int)f でキャストか %f 使用。

編集
Post Share
子ページ

子ページはありません

同階層のページ
  1. printf 標準入出力関数
  2. printfで数値を表示する方法
  3. coutによるコンソール出力
  4. cinによる入力(パラメータ渡し)