PRINTF(3) PRINTF(3) 名前 printf, fprintf, sprintf, snprintf, vprintf, vfprintf, vsprintf, vsnprintf - 整形された書式へ変換する関数 書式 #include 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 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)がある。変換文字は、それぞれがゼロ個以上の 引数を取る。変換文字は文字% で始まる。(型の格上げの後では) 引数は変換文字が表す型と正確に対応しなければならない。% の 28 January 1996 1 PRINTF(3) PRINTF(3) 後に続いて、次のような文字が現れる: +o 以下に示すゼロ個以上のフラグ( 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 の両方が与えられている場合には、- が優先さ れる。 ' ' (1個の半角スペース)符号付き変換(d, e, E, f, g, G, i) によって生成された正の数字の前に空白が置かれることを 指定する。 + 符号付き変換によって出力される数字のまえに、常に符号 が置かれることを指定する。+ と半角スペースの両方が使 われている場合には、+ が優先される。 ' ロケールの情報が何かを示している場合、引数が数値であ るときには出力をグループ化することを指定する。多くの バージョンのgcc が、このオプションを構文解析できずに 、警告(ワーニング)を発することに注意すること。 +o 最小のフィールド長を指定する10進数で示されたオプショ ン文字列。変換された値がフィールド長よりも短い文字数 になる場合、フィールドの左側(左揃いのフラグが与えられ る場合には右側)はスペースで埋められる。 28 January 1996 2 PRINTF(3) PRINTF(3) +o オプションで指定する精度。これは、ピリオド (`.') とそ れに続くオプションの10進数という形で示される。数字を 省略した場合、精度はゼロとみなされる。d, i, o, u, x, X 変換の場合には、変換に使用される最小の桁数を与える。e, E, f 変換の場合、小数点のあとに現れる数字の桁数を与え る。g とG 変換の場合、有効数字の最大桁数である。s 変 換の場合には文字列から出力される文字数の最大値である 。 +o オプション文字h は、次のd, i, o, u, x, X 変換が、short int またはunsigned short int 型の引数に対応すること、 もしくはn 変換がshort int を指すポインタ引数に対応す ることを指定する。 +o オプション文字l (エル)は、引き続くd, i, o, u, x, X 変 換がlong int またはunsigned long int 引数へのポインタ に適用されることを指定する。もしくは、引き続くn 変換 がlong int 引数へ対応していることを指定する。Linux は 、ふたつのl フラグをq またはL と同義に使用できるとい う ANSI にはない機能を提供している。このように、ll は 実数変換と併用して使用することができる。しかし、この 使用方法は推奨していない。 +o 文字L はe, E, f, g, G 変換はlong double 引数に対応す ること、そしてd, i, o, u, x, X 変換はlong long 引数に 対応することを指定する。long long はANSI C で明記され ていないこと、そしてそのために全ての機種に移植可能で はないことに注意すること。 +o オプション文字q 。これはL と同一である。ll, L, そしてq の使用にについてのコメントには「準拠」のセクションと 「バグ」のセクションを見ること。 +o 文字Z は、続く整数がsize_t 引数に対応する変換(d, i, o, u, i, x, X) であることを指定する。 +o 適用される変換の型を指定する文字。 フィールド長や精度(もしくは、その両方)は数字のかわりにアス タリスク `*' によって示されることもある。この場合、int 引 数がフィールド長や精度を指定する。負のフィールド長は、左揃 えのフラグに続く正のフィールド長として扱われる。負の精度は 無視される。 28 January 1996 3 PRINTF(3) PRINTF(3) 変換文字とその意味は以下の通りである。 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 より小さい場合、または精度以上であった場合に 使用される。後を埋めるゼロは、変換された結果の小数部 分の最後から除かれる。すなわち、小数点は少なくても1 つのゼロではない数字が続く場合にのみ現れる。 c int 引数はunsigned char に変換され、その結果に対応す る文字が書き込まれる。 s 文字型の配列へのポインタ(文字列へのポインタ)であるこ とが期待されている``char *'' 引数。配列からの文字は終 端文字NUL まで(終端文字は含まれずに)出力される。精度 が指定された場合には、指定された字数以上は出力されな い。精度が与えられた場合には、終端文字が存在する必要 はない。精度が指定されていなかったり、その値が配列の 28 January 1996 4 PRINTF(3) PRINTF(3) 大きさより大きな場合には、配列は終端文字NUL を含んで いなければならない。 p ``void *'' と表されるポインタである引数が( %#x または %#lx のような)16進数で出力される。 n これまでに出力された文字数が``int *'' (またはそれと等 価な)ポインタ引数で示された整数に保存される。引数の変 換は行わない。 % `%' 一文字が出力される。変換される引数は無い。完全な 変換の記法で表すと `%%' である。 フィールド長の指定が無かったり、実際の長さよりも小さくても 、フィールドの切り詰められることはない。変換の結果がフィー ルド長よりも長い場合には、フィールドは変換の結果を含むよう に拡張される。 例 日付と時間を `Sunday, July 3, 10:02' の形式で出力するには( ここで、weekday とmonth は、文字列へのポインタである): #include fprintf(stdout, "%s, %s %d, %.2d:%.2d\n", weekday, month, day, hour, min); πを5桁で出力するには: #include #include fprintf(stdout, "pi = %.5f\n", 4 * atan(1.0)); 128 バイトの文字列を確保し、そこに出力するには: #include #include #include 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); } 28 January 1996 5 PRINTF(3) PRINTF(3) 関連項目 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 は無限に長い文字列を仮定しているので、 呼び出し側は実際の領域からあふれないように注意しなければな らない。これは、保証することが不可能であることが多い。 28 January 1996 6