PRINTF(3)

名前
printf, fprintf, sprintf, snprintf, vprintf, vfprintf, vsprintf, vsnprintf - 整形された書式へ変換する関数

書式
#include <stdio.h>

int printf(const char *format, ...);
int fprintf(FILE *stream, const char *format, ...);
int sprintf(char *str, const char *format, ...);
int snprintf(char *str, size_t size, const char *format, ...);

#include <stdarg.h>

int vprintf(const char *format, va_list ap);
int vfprintf(FILE *stream, const char *format, va_list ap);
int vsprintf(char *str, const char *format, va_list ap);
int vsnprintfvsnprintf(char *str, size_t size, const char *format, va_list ap);

説明
printf 関数グループは、以下で述べるように、 format に従って出力を生成するものである。 printf と vprintf は出力を stdout （標準出力ストリーム)に書き出す。 fprintf と vfprintf は与えられた出力を stream に書き出す。 sprintf, snprintf, vsprintf そして vsnprintf は文字列 str に書き込む。

これらの関数は format 文字列の制御に従って出力を書き込んでいる。 この文字列は、これに続く引数（または stdarg(3) 機構を使って渡された可変長引数) が出力のためにどのように変換されるのかを指定している。

上記の関数は書き込まれた文字の個数を返す （文字列の最後を示すために使用する`\0'は含まれない）。 snprintf と vsnprintf は、（文字列の終端にある'\0'を含めて） size バイトを越える文字数を書き込まない。 そして、この制限によって出力が中断された場合には-1を返す。

フォーマット用の文字列はゼロ個以上の命令(directives)によって 構成されている。命令には、 出力ストリームにそのままコピーされる( % 以外の)通常の文字と変換文字(conversion specifications)がある。 変換文字は、それぞれがゼロ個以上の引数を取る。 変換文字は文字 % で始まる。 (型の格上げの後では)引数は変換文字が表す型と正確に対応しなければならない。 % の後に続いて、次のような文字が現れる：

•   以下に示すゼロ個以上のフラグ( flags):

    #   は、数値が``別の形式''に変換されることを指定する。 c, d, i, n, p, s, u で示される変換については、このオプションは意味を持たない。 o 変換の場合、出力文字列の最初に強制的に0を付加するために 数字の精度が増やされる(明示的に精度をゼロに指定して0が出力された場合を除く)。 x と X 変換の場合、数値が0でないときには文字列 `0x' ( X 変換の場合には `0X' ) が前に添付される。 e, E, f, g, G 変換では、 小数点に続く数字がなくても、 結果は常に小数点を含んでいる。 (通常は、小数点の後に数字が続く場合に限って、結果のなかに 小数点が表れる)。 g と G 変換の場合、他の変換とは異なり、後に続くゼロが結果から切り取られない。

    0   ゼロを埋めることを指定する。 n を除くすべての変換で、変換した値の左側に 空白文字の代わりにゼロを埋める。 数値の変換と同時に精度が指定されている場合 (d, i, o, u, i, x, X) には、この 0 フラグは無視される。

    -   （負のフィールド長を表すフラグ）変換値がフィールド境界で左揃えになる ことを指示する。 n 変換を除いて、変換された値は 空白文字やゼロで左側ではなく右側を埋められる。 - と 0 の両方が与えられている場合には、 - が優先される。

    ' ' （１個の半角スペース） 符号付き変換 (d, e, E, f, g, G, i) によって生成された正の数字の前に空白が置かれることを 指定する。

    +   符号付き変換によって出力される数字のまえに、常に符号が置かれることを 指定する。 + と半角スペースの 両方が使われている場合には、 + が優先される。

    '   ロケールの情報が何かを示している場合、 引数が数値であるときには出力をグループ化することを指定する。 多くのバージョンの gcc が、このオプションを構文解析できずに、 警告(ワーニング)を発することに注意すること。

•   最小のフィールド長を指定する10進数で示されたオプション文字列。 変換された値がフィールド長よりも短い文字数になる場合、フィールドの左側 (左揃いのフラグが与えられる場合には右側)はスペースで埋められる。

•   オプションで指定する精度。 これは、ピリオド (`.') とそれに続くオプションの10進数という形で示される。 数字を省略した場合、精度はゼロとみなされる。 d, i, o, u, x, X 変換の場合には、変換に使用される最小の桁数を与える。 e, E, f 変換の場合、小数点のあとに現れる数字の桁数を与える。 g と G 変換の場合、有効数字の最大桁数である。 s 変換の場合には文字列から出力される文字数の最大値である。

•   オプション文字 h は、次の d, i, o, u, x, X 変換が、 short int または unsigned short int 型の引数に対応すること、もしくは n 変換が short int を指すポインタ引数に対応することを指定する。

•   オプション文字 l (エル)は、引き続く d, i, o, u, x, X 変換が long int または unsigned long int 引数へのポインタに適用されることを指定する。もしくは、引き続く n 変換が long int 引数へ対応していることを指定する。 Linux は、ふたつの l フラグを q または L と同義に使用できるという ANSI にはない機能を提供している。 このように、 ll は実数変換と併用して使用することができる。 しかし、この使用方法は推奨していない。

•   文字 L は e, E, f, g, G 変換は long double 引数に対応すること、そして d, i, o, u, x, X 変換は long long 引数に対応することを指定する。 long long は ANSI C で明記されていないこと、そしてそのために全ての機種に 移植可能ではないことに注意すること。

•   オプション文字 q 。 これは L と同一である。 ll, L, そして q の使用にについてのコメントには「準拠」のセクションと 「バグ」のセクションを見ること。

•   文字 Z は、続く整数が size_t 引数に対応する変換 (d, i, o, u, i, x, X) であることを指定する。

•   適用される変換の型を指定する文字。

フィールド長や精度(もしくは、その両方)は数字のかわりにアスタリスク `*' によって示されることもある。 この場合、 int 引数がフィールド長や精度を指定する。 負のフィールド長は、 左揃えのフラグに続く正のフィールド長として扱われる。 負の精度は無視される。

変換文字とその意味は以下の通りである。

diouxX
    int 引数(もしくは同等な別の型の引数)を符号つき10進数 (d そして i), 符号なし8進数 (o), 符号なし10進数 (u), 符号なし16進数 (x と X) のいずれかに変換する。 x 変換に abcdef の文字が 使用される。また、 X 変換には ABCDEF の文字が使用される。 (もし指定されている場合には)精度は出力しなければならない最小の桁数を与える。 変換された値がそれより小さな桁数である場合、数字の左側はゼロで埋められる。

eE  double 引数が、丸められて [-]d.ddde\*(Pmdd の形に変換される。 小数点の前には一桁の数字があり、その後の桁数は精度で指定された 桁数になる。 精度が指定されなかった場合には6として扱われ、 精度がゼロである場合には小数点が現れない。 E 変換は指数を表現するときに ( e ではなく) E を用いる。 指数は少なくても二桁になっている。 すなわち、その値がゼロならば、指数は 00 である。

f   double 引数が丸められて [-]ddd.ddd の形の10進表現に変換される。 ここで小数点の後の桁数は指定された精度に等しい。 精度が指定されていない場合には 6 として扱われる。 精度としてあらわにゼロが指定されている場合には、小数点以下が現れない。 小数点が現れる場合には、少なくても一つの数字が小数点の前に現れる。

g   double 引数が f または e ( G 変換の場合には E ) の形式に変換される。 精度は表示する桁数を指定する。 精度が指定されない場合には、 6 桁が与えられる。 精度がゼロである場合には、1桁として取り扱われる。 形式 e は、変換される値が -4 より小さい場合、または精度以上であった場合に 使用される。 後を埋めるゼロは、変換された結果の小数部分の最後から除かれる。 すなわち、小数点は少なくても１つのゼロではない数字が続く場合にのみ 現れる。

c   int 引数は unsigned char に変換され、その結果に対応する文字が書き込まれる。

s   文字型の配列へのポインタ(文字列へのポインタ)であることが期待されている ``char *'' 引数。 配列からの文字は 終端文字 NUL まで(終端文字は含まれずに)出力される。 精度が指定された場合には、指定された字数以上は出力されない。 精度が与えられた場合には、終端文字が存在する必要はない。 精度が指定されていなかったり、その値が配列の大きさより大きな場合には、 配列は終端文字 NUL を含んでいなければならない。

p   ``void *'' と表されるポインタである引数が ( %#x または %#lx のような)16進数で出力される。

n   これまでに出力された文字数が ``int *'' (またはそれと等価な)ポインタ引数で示された整数に保存される。 引数の変換は行わない。

%   `%' 一文字が出力される。 変換される引数は無い。 完全な変換の記法で表すと `%%' である。

フィールド長の指定が無かったり、実際の長さよりも小さくても、 フィールドの切り詰められることはない。 変換の結果がフィールド長よりも長い場合には、フィールドは 変換の結果を含むように拡張される。

例
日付と時間を `Sunday, July 3, 10:02' の形式で出力するには (ここで、 weekday と month は、文字列へのポインタである)：
    #include <stdio.h>
    fprintf(stdout, "%s, %s %d, %.2d:%.2d\n",
    	weekday, month, day, hour, min);

πを５桁で出力するには：
    #include <math.h>
    #include <stdio.h>
    fprintf(stdout, "pi = %.5f\n", 4 * atan(1.0));

128 バイトの文字列を確保し、そこに出力するには：
    #include <stdio.h>
    #include <stdlib.h>
    #include <stdarg.h>
    char *newfmt(const char *fmt, ...)
    {
    		char *p;
    		va_list ap;
    		if ((p = malloc(128)) == NULL)
    			return (NULL);
    		va_start(ap, fmt);
    		(void) vsnprintf(p, 128, fmt, ap);
    		va_end(ap);
    		return (p);
    }

関連項目
printf(1), scanf(3)

準拠
fprintf, printf, sprintf, vprintf, vfprintf, そして vsprintf 関数は ANSI C3.159-1989 (``ANSI C'') に準拠している。

q フラグは long long の BSD 4.4 の記法である。一方、整数変換における ll や L の使用は GNU の記法である。

これらの関数の Linux 版は GNU libio ライブラリーに基づいている。 より簡明な説明については GNU libc (glibc-1.08) の info 文書を見ること。

バグ
Linux での浮動小数点実数の変換がメモリー・リークを起こすことがある。

すべての関数は完全に ANSI C3.159-1989 に準拠している。 しかし、 追加の q, Z , ' フラグが提供されており、同様に L と l フラグの動作も変更されている。 後者は ANSI C3.159-1989 で定義されているフラグの振る舞いを変えるものである。 従って、後者はバグとみなされるかもしれない。

%p フォーマットで ( 0 フラグや精度を指定して)ゼロを埋める効果、 %n や %p 変換に対して # フラグを指定した場合の親切効果(# を無視すること)の ような無意味な組合せは標準ではない。 このような組み合わせは避けるべきである。

ANSI C で定義されたフラグの組み合わせには 意味をなさないものがある (例えば %Ld) 。 それらは Linux 上では良く定義された振る舞いを持つであろうが、 他のアーキテクチャーでもそうである必要はない。 それゆえに、ほとんどの場合、 ANSI C で定義されていないフラグを通常使用しない方が良い。 diouxX 変換または ll とともに L を使用するのならば、 q を使用するべきである。

実数変換において L と等価に使用されるといった q の使用方法は BSD 4.4 のそれとは同じではない。

sprintf と vsprintf は無限に長い文字列を仮定しているので、呼び出し側は 実際の領域からあふれないように注意しなければならない。 これは、保証することが不可能であることが多い。