sprintfとは? わかりやすく解説

sprintf

(PHP 4, PHP 5)
sprintf — フォーマットされた文字列を返す

説明

string sprintf ( string format [, mixed args [, mixed ...]] )
フォーマット文字列 format に基づき生成された文字列を返します。
フォーマット文字列は 0 個以上のディレクティブ(指示子) により構成されます。ディレクティブには、そのまま結果にコピーされる (% を除く) 通常の文字と変換指定子 (conversion specifications) があり、 取り出される際はどちらもそれ自身がパラメータとなります。このことは sprintf() の場合だけでなく printf() の場合も同様です。
各変換指定子は、パーセント記号 (%) の後に これらの要素が一つ以上続いたものになります。
  1. オプションの符号指定子。これは、 数値で符号 (- あるいは +) を使用するよう指定します。 デフォルトでは、数値が負の場合の - 符号のみが使用されます。 この指定子により、正の数にも強制的に + 符号をつけることができます。 これは PHP 4.3.0 で追加されました。
    オプションのパディング指定子。これは、 文字列が正しい長さになるまでどんな文字で埋めるかということを 指定します。これは空白かまたは 0 (文字 '0') のいずれかです。デフォルトでは空白で埋められます。 これ以外のパディング文字を指定するには、その文字の前に 単一引用符 (') を置きます。 後述の例を参照ください。
  2. オプションのアラインメント指定子。これは、 結果を左寄せまたは右寄せにしたい場合に指定します。 デフォルトは右寄せです。ここで - 文字を指定すると左寄せとなります。
  3. オプションの数字。これは表示幅指定子です。 結果を(最低)何桁にするかを指定します。
  4. オプションの精度指定子。これは、 浮動小数点数に対して数字を何桁まで表示するかを指定します。 文字列に対して使用した場合は、これは切り捨て位置として働きます。 この文字数を超える文字を切り捨てられます。
  5. 型指定子。引数を何の型として扱うかを指定します。 指定できる型を以下に示します。
    % - パーセント文字。引数は不要です。
    b - 引数を整数として扱い、 バイナリの数値として表現します。
    c - 引数を整数として扱い、その ASCII 値の文字として表現します。
    d - 引数を整数として扱い、 10 進数として表現します。
    e - 引数を科学記法として扱います (例 1.2e+2)。
    u - 引数を整数として扱い、符号無しの 10 進数として表現します。
    f - 引数を double として扱い、 浮動小数点数として表現します。
    F - 引数を float として扱い、 浮動小数点数として表現します (ロケールに依存しません)。 PHP 4.3.10 および PHP 5.0.3 以降で使用可能です。
    o - 引数を整数として扱い、 8 進数として表現します。
    s - 引数を文字列として扱い、表現します。
    x - 引数を整数として扱い、16 進数として (小文字で)表現します。
    X - 引数を整数として扱い、16 進数として (大文字で)表現します。


PHP 4.0.6 以降、フォーマット文字列における引数の 番号付け/交換 がサポートされました。以下に例を示します。 例 2286. 引数の交換
<?php
$format = 'There are %d monkeys in the %s';
printf($format,$num,$location);
?>

この出力は、"There are 5 monkeys in the tree" のようになります。 ここで、フォーマット文字列が別のファイルにある場合を考えてみましょう。 これは、出力を国際化したりする場合に行われる可能性があります。 たとえばフォーマット文字列が次のように書き換えられたとすると、 例 2287. 引数の交換
<?php
$format = 'The %s contains %d monkeys';
printf($format, $num, $location);
?>

ここで、問題が発生します。フォーマット文字列における置換指示子の順番は、 コードにおける引数の順番と一致していません。 だからといってコードを変更するのではなく、 むしろ置換指示子が参照するフォーマット文字列のほうで指示を行う方が望ましいでしょう。 フォーマット文字列を次のように書き換えてみましょう。 例 2288. 引数の交換
<?php
$format = 'The %2$s contains %1$d monkeys';
printf($format, $num, $location);
?>

こうすることによるもうひとつの利点は、 同じ置換指示子を複数回使用する際にコードに引数を追加せずにすむことです。 例えば、次のようになります。 例 2289. 引数の交換
<?php
$format = 'The %2$s contains %1$d monkeys.
           That\'s a nice %2$s full of %1$d monkeys.';
printf($format, $num, $location);
?>


printf(), sscanf(), fscanf(), vsprintf(), number_format() も参照ください。

例 2290. printf() のさまざまな例
<?php
$n =  43951789;
$u = -43951789;
$c = 65; // ASCII コードの 65 は 'A' です

// %% に注目しましょう。これは、リテラル '%' を文字として出力します
printf("%%b = '%b'\n", $n); // 2 進表現
printf("%%c = '%c'\n", $c); // ascii 文字を表示します。chr() 関数と同じです
printf("%%d = '%d'\n", $n); // 標準の整数表現
printf("%%e = '%e'\n", $n); // 科学記法
printf("%%u = '%u'\n", $n); // 正の整数の、符号なし整数表現
printf("%%u = '%u'\n", $u); // 負の整数の、符号なし整数表現
printf("%%f = '%f'\n", $n); // 浮動小数点表現
printf("%%o = '%o'\n", $n); // 8 進表現
printf("%%s = '%s'\n", $n); // 文字列表現
printf("%%x = '%x'\n", $n); // 16 進表現 (小文字)
printf("%%X = '%X'\n", $n); // 16 進表現 (大文字)

printf("%%+d = '%+d'\n", $n); // 正の整数に符号指定子を使用
printf("%%+d = '%+d'\n", $u); // 負の整数に符号指定子を使用
?>
このプログラムの出力内容は次のようになります。

%b = '10100111101010011010101101'
%c = 'A'
%d = '43951789'
%e = '4.39518e+7'
%u = '43951789'
%u = '4251015507'
%f = '43951789.000000'
%o = '247523255'
%s = '43951789'
%x = '29ea6ad'
%X = '29EA6AD'
%+d = '+43951789'
%+d = '-43951789'

     

例 2291. printf() の文字列指定子
<?php
$s = 'monkey';
$t = 'many monkeys';

printf("[%s]\n",      $s); // 標準の文字列出力
printf("[%10s]\n",    $s); // 空白を使用して右詰め
printf("[%-10s]\n",  $s); // 空白を使用して左詰め
printf("[%010s]\n",  $s); // ゼロ埋めは文字列でも可能です
printf("[%'#10s]\n",  $s); // ゼロの代わりに独自の文字 '#' で埋めます
printf("[%10.10s]\n", $t); // 左詰めを行い、10 文字以上は切り捨てます
?>
このプログラムの出力内容は次のようになります。

[monkey]
[    monkey]
[monkey    ]
[0000monkey]
[####monkey]
[many monke]

     

例 2292. sprintf: 整数を 0 でパディング
<?php
$isodate = sprintf("%04d-%02d-%02d", $year, $month, $day);
?>

例 2293. sprintf: 通貨をフォーマットする例
<?php
$money1 = 68.75;
$money2 = 54.35;
$money = $money1 + $money2;
// echo $money は "123.1" を出力します。
$formatted = sprintf ("%01.2f", $money);
// echo $formatted は "123.10"を出力します
?>

例 2294. sprintf(): 科学記法
<?php
$number = 362525200;

echo sprintf("%.3e", $number); // 3.63e+8 を出力します
?>



printf

(sprintf から転送)

出典: フリー百科事典『ウィキペディア(Wikipedia)』 (2025/09/28 07:49 UTC 版)

printf(プリントエフ)は、C言語標準ライブラリに属し、ヘッダーファイル stdio.h で宣言されている関数である。引数で与えられた書式付きの文字列を、環境によって設定された標準出力 (stdout) に出力する。その機能は国際標準規格「ISO/IEC 9899:1999」(通称C99)および日本産業規格(旧称・日本工業規格)による翻訳「JIS X 3010:2003」においてprintf関数は,与えられた実引数の前にstdoutを実引数として付加したfprintf関数と等価とする。と規定されている (7.19.6.3)。

この関数は、第1引数に与えられた文字列を出力する。C言語の他の単純な入出力関数に比べ、比較的複雑な構造を持っており、第1引数の文字列のなかで書式を指定することで、第2引数以降の任意の数の引数(可変長引数)を、書式に従って出力することができる。また、整数型int型)の戻り値を持ち、出力に成功した場合には転送したバイト数、出力に失敗した場合には負数を返却する。

形式

#include <stdio.h>
int printf(const char * restrict format, ...);

書式化文字列

上記形式における第一引数には、それに続く実引数の変換方法を指定する。書式化文字列には、通常のマルチバイト文字または%で始まる変換指定のいずれかの指令を0個以上含む。マルチバイト文字が含まれ、かつ文字コードがシフトシーケンスに依存する場合には、書式化文字列は初期シフト状態で始まり、初期シフト状態で終わらなければならない。書式指定を行う%それぞれを書式指定子と呼ぶ。

変換指定

変換指定は次の形式をとる。([ ]内は省略可能)

%[引数順][フラグ][最小フィールド幅][.精度][長さ修飾子]変換指定子

引数順 (POSIX)

これは標準C規格の仕様ではなく、POSIXで規定されている拡張である。

書式文字列において%の代わりに%m$を記述することで、続く可変長引数のうちどれを使うかを番号mで指定できる。 例えば、

const char* fmt = "Invalid command %1$s at line %2$d.\n";
const char* cmd = "hoge";
const int lineNumber = 20;
printf(fmt, cmd, lineNumber);

とした場合、

Invalid command hoge at line 20.

と表示される。これだけならば大きな意味はないが、例えばメッセージを翻訳(ローカライズ)する際、

const char* fmt = "%2$d行目のコマンド %1$s は不正です。\n";

というように書式文字列だけをローカライズする[注釈 1]ことで、可変長引数の指定順を変更せずに、

20行目のコマンド hoge は不正です。

という自然な語順の出力を得ることができる[注釈 2]

フラグ

変換指定のフラグは以下の通り。

フラグ 意味
- フィールドの左寄せ
+ 常に符号を出力
空白 数値が正または 0 の場合は符号の代わりに空白を出力
# 代替形式。基数を表すプレフィックスの出力等
0 出力文字数が最小フィールド幅未満の場合は'0'を出力

長さ修飾子

修飾子 意味 導入バージョン
hh 実引数はchar C99以降
h 実引数はshort 全バージョン
l(エル) 実引数はlong型、wint_t型、wchar_t型またはdouble[注釈 3] wint_tおよびwchar_tについてはC95以降、doubleについてはC99以降
ll(エルエル) 実引数はlong long C99以降
j 実引数はintmax_t C99以降
z 実引数はsize_t C99以降
t 実引数はptrdiff_t C99以降
L 実引数はlong double 全バージョン

Cの可変長引数には「既定の実引数拡張」(default argument promotion) と呼ばれる暗黙の型変換が適用される[1][2]。整数型の場合は汎整数拡張と同じであり、順位 (rank) がintよりも低いcharsigned charunsigned charおよびshortの値はintに変換される。unsigned shortについては、型の値をすべてintで表現できる環境の場合はintに、そうでない場合はunsigned intに変換される。floatの値はdoubleに変換される。そのため、hhhおよびdoubleに対するlは、printfでは省略可能である[注釈 4]。もともとdoubleに対するlは必要なかったが、あまりに多くのプログラマが間違いを犯し続けたため、標準規格において追認されたという歴史的な経緯がある[3]。ただし、scanfでは実引数としてポインタが渡されるため、長さ修飾子の指定による区別が必要となる。

なお、C99で追加されたint32_tint64_tなどのビット数が指定された整数型の実引数に対して、これらの長さ修飾子を直接使用した場合の動作は未定義である。仮に特定の実装では期待通り動作したとしても、データ型モデルによっては移植の際に非互換が生じることもある[注釈 5]。これらの固定幅の整数型を実引数として使用する際は、明示的な型キャストをするか、inttypes.hヘッダーに定義されているPRIで始まるマクロを利用する必要がある[4][5]

変換指定子

指定子 意味 導入バージョン
d, i 10進符号付き整数 全バージョン
u 10進符号無し整数 全バージョン
o 8進符号無し整数 全バージョン
x, X 16進符号無し整数( X は大文字で出力) 全バージョン
e, E 指数形式浮動小数点数( E は大文字で出力) 全バージョン
f, F 小数形式浮動小数点数( F は大文字で出力) 全バージョン
g, G e または f 形式のうち適した方( G は大文字で出力) 全バージョン
a, A 16進浮動小数点( A は大文字で出力) C99以降
c 文字 全バージョン
s 文字列 全バージョン
p ポインタの値 全バージョン
n 整数変数に出力済み文字数を格納 全バージョン
% '%'の出力 全バージョン

関連する関数

fprintf

fprintfは、引数にファイルポインタfpが追加され、標準出力の代わりにfpへ出力する変種である。

#include <stdio.h>
int fprintf(FILE * restrict fp, const char * restrict format, ...);

sprintf, snprintf

sprintfとsnprintfは、引数にchar配列の要素へのポインタstrが追加されたもので、標準出力の代わりにstrへ出力する変種である。snprintfは、さらにstrに書き込んで良い文字数を指定する引数が追加されたものであるが、Cの標準規格に収録されたのはC99からである。

#include <stdio.h>
int sprintf(char * restrict str, const char * restrict format, ...);
int snprintf(char * restrict str, size_t size, const char * restrict format, ...);

wprintf, fwprintf, swprintf

wprintf, fwprintf, swprintfは、それぞれprintf, fprintf, snprintfに対応し、ワイド文字を使用するものである。C95で標準化された。sprintfに直接対応するワイド文字バージョンの関数(出力バッファサイズを受け取らない関数)は存在しない[注釈 6]

#include <stdio.h> /* または wchar.h */
int wprintf(const wchar_t * restrict format, ...);
int fwprintf(FILE * restrict fp, const wchar_t * restrict format, ...);
int swprintf(wchar_t * restrict str, size_t size, const wchar_t * restrict format, ...);

va_listを引数に取るもの

ここまでに挙げたprintfとその変種に対して、可変個引数部分をva_listに変化させた種類が存在する。それぞれ、関数名の頭にvを付けた名称となっている。vsnprintfはC99で標準化された。

#include <stdio.h>
int vprintf(const char * restrict format, va_list args);
int vfprintf(FILE * restrict fp, const char * restrict format, va_list args);
int vsprintf(char * restrict str, const char * restrict format, va_list args);
int vsnprintf(char * restrict str, size_t size, const char * restrict format, va_list args);
#include <stdio.h> /* または wchar.h */
int vwprintf(const wchar_t * restrict format, va_list args);
int vfwprintf(FILE * restrict fp, const wchar_t * restrict format, va_list args);
int vswprintf(wchar_t * restrict str, size_t size, const wchar_t * restrict format, va_list args);

安全性を向上させたもの

C11のAnnex K Bounds‐checking interfacesで規定された、安全性を向上させた種類が存在する。それぞれ、関数名の末尾に_sを付けた名称となっている。これらの関数は、__STDC_WANT_LIB_EXT1__1に定義した上で対応するヘッダーをインクルードすると宣言される。

#define __STDC_WANT_LIB_EXT1__ 1
#include <stdio.h>
#include <wchar.h>

int printf_s(const char * restrict format, ...);
int fprintf_s(FILE * restrict fp, const char * restrict format, ...);
int sprintf_s(char * restrict str, rsize_t size, const char * restrict format, ...);
int snprintf_s(char * restrict str, rsize_t size, const char * restrict format, ...);
int vprintf_s(const char * restrict format, va_list arg);
int vfprintf_s(FILE * restrict fp, const char * restrict format, va_list arg);
int vsprintf_s(char * restrict str, rsize_t size, const char * restrict format, va_list arg);
int vsnprintf_s(char * restrict str, rsize_t size, const char * restrict format, va_list arg);

int wprintf_s(const wchar_t * restrict format, ...);
int fwprintf_s(FILE * restrict fp, const wchar_t * restrict format, ...);
int swprintf_s(wchar_t * restrict str, rsize_t size, const wchar_t * restrict format, ...);
int snwprintf_s(wchar_t * restrict str, rsize_t size, const wchar_t * restrict format, ...);
int vwprintf_s(const wchar_t * restrict format, va_list arg);
int vfwprintf_s(FILE * restrict fp, const wchar_t * restrict format, va_list arg);
int vswprintf_s(wchar_t * restrict str, rsize_t size, const wchar_t * restrict format, va_list arg);
int vsnwprintf_s(wchar_t * restrict str, rsize_t size, const wchar_t * restrict format, va_list arg);

以下のような機能が追加されている。

  • FILE*や文字列の引数(%sに対応する可変長引数部分の引数も含む)に対するNULLポインタチェック
  • 出力先バッファサイズのチェック
  • %n書式の禁止

エラーは実行時に検出され、現在設定されている制約ハンドラー (constraint handler) 関数が呼ばれる。

Windows API

Microsoft Windows用のWindows APIには、sprintf()snprintf()などによく似た名前の関数として以下のようなAPIが用意されている[8][9]

// winuser.h
int wsprintfA(LPSTR unnamedParam1, LPCSTR unnamedParam2, ...);
int wsprintfW(LPWSTR unnamedParam1, LPCWSTR unnamedParam2, ...);
int wvsprintfA(LPSTR unnamedParam1, LPCSTR unnamedParam2, va_list arglist);
int wvsprintfW(LPWSTR unnamedParam1, LPCWSTR unnamedParam2, va_list arglist);
// shlwapi.h
int wnsprintfA(PSTR pszDest, int cchDest, PCSTR pszFmt, ...);
int wnsprintfW(PWSTR pszDest, int cchDest, PCWSTR pszFmt, ...);
int wvnsprintfA(PSTR pszDest, int cchDest, PCSTR pszFmt, va_list arglist);
int wvnsprintfW(PWSTR pszDest, int cchDest, PCWSTR pszFmt, va_list arglist);

ここで、LPSTRPSTRchar*LPCSTRPCSTRconst char*LPWSTRPWSTRwchar_t*LPCWSTRPCWSTRconst wchar_t*に相当するtypedef型エイリアスである。Wサフィックスはワイド文字によるUnicode文字セット、AサフィックスはANSIマルチバイト文字セット(MBCS)を意味する。プロジェクトのUnicode対応設定(マクロシンボルUNICODEの定義有無)によって関数の実装がW版またはA版に切り替わるwsprintfマクロやwnsprintfマクロなども用意されている。

いずれもfloatdoubleといった浮動小数点数型の書式化には対応しておらず、C/C++の標準ライブラリ関数とは互換性がない。Cランタイムライブラリ (CRT) に依存せず、Windows環境限定で標準的に使えることがメリットだが、これらの使用は推奨されておらず、<strsafe.h>で定義されているセーフ文字列関数の使用が推奨されている[10]

なお、Windows API関数の呼び出し規約は、ほぼすべて_stdcall__stdcallWINAPI / STDAPICALLTYPE)であるが、上記のうち可変長引数...を受け取るAPI関数は例外的に_cdecl__cdeclWINAPIV / STDAPIVCALLTYPE)となっている。x86の場合は引数の受け渡し動作が呼び出し規約に左右される。

コード例

#include <stdio.h>

int main(void)
{
    int a = 1234;
    printf("%d %o %x\n", a, a, a);
    printf("%s %c\n", "abc", 'x');
    return 0;
}

上記のコードをコンパイルし実行すると、次の出力が得られる。

1234 2322 4d2
abc x

脆弱性

一般に、書式文字列を外部や利用者から自由に指定できる状態とすることはセキュリティホールの温床となるため望ましくない。特に%n書式を用いたものが有名である[11]。Visual C++のCRTでは既定で%n書式が無効化されており、使用できなくなっている[12]

また、書式化文字列中の書式指定子と実引数の数や型が正しく対応していない場合は未定義動作を引き起こす。Cの可変長引数は型消去によって実現される仕組みであるため、printf()の内部では書式と実引数の数や型の不一致を検出することができず、本質的に安全性が欠如している。正しい書式を与えることはプログラマ側の責任である。

なお、引数で受け取ったバッファに書式化された文字列を出力する関数群は、バッファサイズを超えてデータを書き込んでしまうと未定義動作を引き起こす。特に、sprintf()vsprintf()といったバッファサイズ(書き込み可能な最大サイズ)を指定することのできない関数は潜在的なバッファオーバーフローの脆弱性を抱えているため使うべきではなく、代わりにC99で追加されたsnprintf()vsnprintf()を使うべきである。

他言語

C言語から派生したC++D言語はもとより、PHP[13]Ruby[14]Perlなど他の言語でもprintfが実装されている。Python 2.xではprintだったが、3.xではprint関数となった。

また、Ruby[15]やPythonなど、%演算子によってsprintf()相当機能をサポートするものも存在する。Boost C++ライブラリのBoost.Format[16]では、boost::formatクラスの%演算子オーバーロードによって類似の機能を実現している[17]

C++11ではC99のライブラリ関数の多くが取り込まれた。C++20では関数テンプレートstd::format()[18]が、C++23ではstd::print()[19]が追加された。

Unix系オペレーティングシステムのコマンドとして実装されたprintf英語版もある。外部コマンドのほか、Bashなど一部のUnixシェルではビルトインで実装されている。

Java

Java 1.5ではStringクラスにformat()メソッドが、java.io.PrintStreamクラスにformat()メソッドとprintf()メソッドが追加された。

標準出力の場合は、例えば以下のように呼び出すことができる。

System.out.printf("Integer = 0x%02X, Double = %.4f\n", 10, Math.PI);

Javaの可変長引数はObjectの配列だが、intdoubleのようなプリミティブ型の引数はオートボクシング(自動ボックス化)によってプリミティブラッパークラスにラップされて渡されるため、オーバーヘッドはあるものの本質的に型安全である。書式指定に誤りがあった場合はjava.util.IllegalFormatException例外を、また書式指定に対応する実引数が不足していた場合はjava.util.MissingFormatArgumentException例外をスローする。

Javaに限らず、後発のオブジェクト指向言語や動的型付け言語の場合は、可変長引数として使われるコレクション(配列やリスト)が長さ情報を持っており、またコレクション中の各オブジェクトが自分自身の型情報を持っているため、printf()相当機能がバッファ安全かつ型安全に実現できるようになっている。

脚注

注釈

  1. ^ 実際のローカライズ作業では、gettext等によってメッセージカタログから文字列を得るようにコードを記述する。
  2. ^ 類似の順序指定可能な書式化機能を持つものとして、Windows APIFormatMessage()関数や、Microsoft Foundation ClassAfxFormatString2()関数、.NET FrameworkSystem.String.Format()メソッドなどが挙げられる。
  3. ^ 可変長引数では「既定の実引数拡張」により、float型の引数はdouble型へと変換されるため、本来はdoubleに対して修飾子を適用する必要はない。
  4. ^ 変換指定子xXまたはoを使って負の整数値を16進数または8進数に変換する場合は、hhhの有無によって結果が変化する。
  5. ^ 例えばLP64環境ではlong64ビットであり、仮にint64_t型の実引数に対して%ld書式を使用したとしてもほとんどの実装では期待通り動作する可能性が高いが、LLP64環境ではlong32ビットであり、int64_t型の実引数に対して%ld書式を使用すると未定義動作を引き起こす。また、long longは少なくとも64ビット以上の値を表現できることが保証されているが、int64_tと同じ型であるという保証はどこにもなく、int64_t型の実引数に対して%lld書式を使用した場合の動作はやはり未定義となる。同様に、intint32_tが同じ型であるという保証もない。
  6. ^ Microsoft Visual C++には非標準関数としてバッファサイズを受け取らないswprintfが存在するが、バージョン2005 (8.0) 以降では既定で無効化されており、非推奨となっている[6][7]

出典

参考文献

  • JIS X 3010:2003 プログラミング言語C
  • N1570 (PDF) (C11の最終ドラフト)

関連項目

外部リンク




固有名詞の分類


英和和英テキスト翻訳>> Weblio翻訳
英語⇒日本語日本語⇒英語
  

辞書ショートカット

すべての辞書の索引

「sprintf」の関連用語

sprintfのお隣キーワード
検索ランキング

   

英語⇒日本語
日本語⇒英語
   



sprintfのページの著作権
Weblio 辞書 情報提供元は 参加元一覧 にて確認できます。

   
PHP Documentation GroupPHP Documentation Group
Copyright © 1997 - 2025 by the PHP Documentation Group.
ウィキペディアウィキペディア
All text is available under the terms of the GNU Free Documentation License.
この記事は、ウィキペディアのprintf (改訂履歴)の記事を複製、再配布したものにあたり、GNU Free Documentation Licenseというライセンスの下で提供されています。 Weblio辞書に掲載されているウィキペディアの記事も、全てGNU Free Documentation Licenseの元に提供されております。

©2025 GRAS Group, Inc.RSS