PRINTF(3) Linux Programmer's Manual 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 vsnprintf(char *str, size_t size, const char *format, va_list ap);
printf() 関数グループは、以下で述べるように、 format
に従って出力を生成するものである。 printf() と vprintf() は出力を std-
out (標準出力ストリーム) に書そ个后 fprintf() と vfprintf()
は出力を指定された出力 stream に書そ个后 sprintf(), snprintf(),
vsprintf(), vsnprintf() は出力を文字列 str に書すむ。
vprintf(), vfprintf(), vsprintf(), vsnprintf() の各関数はそれぞれ
printf(), fprintf(), sprintf(), snprintf(),
の各関数と等価であり、可変数引た瑤梁紊錣蠅 va_list を 引-
数として呼び出される点だけが異なる。 これらの関数では va_end
マクロは呼び出されない。 当然、呼び出し後の ap の値は未定義である。
アプリケーションは後で自分で va_end(ap) を呼び出す必要がある。
これらの 8 つの関数は format 文字列の制御に従って出力を書そ个后 format
文字列は、これに続く引た (または stdarg(3) の可変長引-
数機構を使ってアクセスでい覦た)
をどのように変換して出力するかを指定する。
返屬り蠱値
成功時には、上気隆愎瑤禄颪込まれた文字数を返す
(文字列の最後を示すために使用する `\0' は数に含まれない)。 snprintf()
と vsnprintf() は、 size バイトを越える文字数を書すまない (size
には文字列の終端にある '\0' もを含まれる)。
この制限によって出力が切り詰められた場合には、
もし十分なスペースがあれば書すまれたであろう文字の個数
(文字列の終端にある '\0' を除く) を返す。 従って、返り値が size
以上だった場合、出力が切り詰められたことを意味する
(後述の注意も参照のこと)。 エラーが発生した場合は、負の数を返す。
フ侫ォー璽マ泪ッ奪ト畔文源字列鵑の離フ侫ォー璽マ泪ッ奪ト
フォーマット文字列は文字の列で、 (もしあるなら)
初期シフト状態で始まり、初期シフト状態で終わる。
フォーマット用の文字列は 0 個以上の命令 (directives)
によって構成される。 命令には、通常文字と変換指定 (conversion specifi-
cations) がある。 通常文字は %
以外の文字で、出力ストリームにそのままコピーされる。
変換指定は、それぞれが 0 個以上の引た瑤鮗茲襦 各変換指定は文字 %
で始まり、 (conversion specifier) で終わる。 %
と変換指定子の間には、0 個以上の 最小
を (この順序で) 置くことがでい襦
引た瑤 (型の格上げの後は)
変換指定子が表す型と正確に対応しなければならない。 デフォルトでは、`*'
や変換指定子が出てくる毎に次の引た瑤鰺弋瓩気譟 引-
数は指定された順序で使用されていく (指定された引-
数の個数が不十分ならエラーとなる)。 また、引た瑤必要な箇所で `%'
の代わりに `%m$'、 `*'の代わりに `*m$' と書くことで、 明示的にどの引-
数を使用するかを指定することもでい襦 ここで 10進の整数 m は希望の引-
数の引た凜螢好箸任琉銘屬鮗┐ (最初の引た瑤糧峭罎 1 である)。
従って、以下の 2つは等価である。
printf("%*d", width, num);
printf("%2$*1$d", width, num);
二番目の書なでは同じ引た瑤魴り返し参照することがでい襦 C99
標準には、 Single Unix Specification 由来の `$' を使った書-
方は含まれていない。 `$' を使ったスタイルを使うと、引-
数を取る変換及び幅と精度の引た瑤
全てこのスタイルで指定しなければならないが、 引た瑤鮠暖颪靴覆 `%%'
フォーマットと混ざっているかもしれない。 `$' で指定される引-
数の番号に空いあってはならない。 例えば、もし引た 1 と 3
が指定されると、引た 2 もフォーマット文字列のどこかで
指定されなければならない。
数値変換には小数点や 1000 単位の区切り文字を使うものもある。
実際にどの文字を使うかはロケールの LC_NUMERIC による。 POSIX
ロケールでは小数点に `.' を用い、 区切り文字は使わない。 従って、
printf("%'.2f", 1234567.89);
は、 POSIX ロケールでは `1234567.89' 、 nl_NL ロケールでは
`1234567,89'、 da_DK ロケールでは `1.234.567,89' となる。
フ侫ラ薀グ以文源字
% 文字の後ろには 0 個以上のフラグ文字が続く。
# 値は``別の形式''に変換される。 o 変換の場合、(先頭文字が 0
になっていない場合に先頭に 0 を追加することで)
出力文字列の最初の文字を 0 にする。 x と X 変換の場合、数値が 0
でないとい砲亙源列 `0x' (X 変換の場合には `0X')
が前に付与される。 a, A, e, E, f, F, g, G 変換では、
小数点に続く数字がなくても、 出力には常に小数点が含まれる
(通常は、小数点の後に数字が続く場合にのみ、
小数点が表示される)。 g と G
変換の場合、他の変換とは異なり、末尾のゼロが変換結果から削除されない。
その他の変換では、結果は未定義である。
0 値をゼロで埋める。 d, i, o, u, x, X, a, A, e, E, f, F, g, G
変換では、変換した値の左側を空白文字の代わりにゼロで埋める。 0
と - が両方とも指定された場合は、 0 フラグは無視される。
精度が数値変換 (d, i, o, u, x, X) と同時に指定された場合には、 0
フラグは無視される。 その他の変換では、動作は未定義である。
- 変換値をフィールド恭Δ悩限靴┐砲垢 (デフォルトは右揃えである)。
n 変換以外では、変換された値は
左側ではなく右側を空白文字やゼロで埋められる。 - と 0
の両方が指定された場合には、 - が優先される。
' ' (1個の半角スペース) 符号付な儡垢農言された正の数字の前に空白
(または空文字列) が置かれる。
+ 符号付な儡垢砲茲辰峠侘呂気譴訖字の前に、常に符号 (+ か -)
が置かれる。
デフォルトでは、符号は負の数字の場合のみ付与される。 +
と半角スペースの 両方が使われている場合には、 + が優先される。
上気 5 つのフラグは C 標準で定義されている。 SUSv2
では、さらにもう一つフラグ文字が規定されている。
' 10進数変換 (i, d, u, f, F, g, G)
において、ロケール情報に指定があれば 1000
単位の区切り文字を出力する。 gcc(1)
の多くのバージョンは、このオプションを解釈することがでい此
警告を出力することに注意せよ。 %'F は SUSv2 には含まれていない。
glibc 2.2 では、さらに一つフラグ文字が追加されている。
I 10進整数変換 (i, d, u)
において、ロケールの代替出力数字があれば、それを用いて出力する。
例えば、 glibc 2.2.3 以降では、ペルシア (`fa_IR') ロケールで
アラビア数字 (Arabic-Indic digits) を出力でい襦
フ侫ィー璽ル襯ド鰭幅
最小のフィールド幅を指定する 10進数の数値文字列 (文字列の最初の文字は
ゼロ以外)。本項目はオプションである。
変換された値の文字数がフィールド長よりも少ない場合、
フィールドの左側をスペースで埋める
(左揃えのフラグがある場合は右側を埋める)。 10進数の文字列の代わりに `*'
や `*m$' (m は 10進整数) を書くこともでい襦 `*' と `*m$'
はそれぞれ、次の引た瑤 m 番目の引た瑤鬟侫ールド幅として
使うことを指定する (これらの引た瑤 int 型でなければならない)。
フィールド幅に負の数が指定された場合は、 `-'
フラグと正の数のフィールド幅として扱われる。
フィールド幅が小さかったり指定がなかったりしても、フィールドが切り詰められる
ことはない。もし変換結果がフィールド幅よりも垢った場合、
フィールドは変換結果が入る幅に垢欧蕕譴襦
精催度
オプションである精度は、ピリオド (`.') とそれに続く10進数という
形式で指定する (10進数はオプション) 。 10進数の文字列の代わりに `*' や
`*m$' (m は 10 進整数)を書くこともでい襦 `*' と `*m$'
はそれぞれ、次の引た瑤 m 番目の引た瑤鮴催戮箸靴 使うことを指定する
(これらの引た瑤 int 型でなければならない)。 精度として `.'
だけが指定されたり、精度が負の数だった場合、 精度はゼロとみなされる。
d, i, o, u, x, X 変換では、表示される最小の桁数を指定する。 a, A, e, E,
f, F 変換では、小数点以下に表示される数字の桁数を指定する。 g と G
変換では、邑数字の最大桁数を指定する。 s と S
変換では、文字列から出力される最大文字数を指定する。
長垢さ欺修ぞ飾子
``整数変換''とは、 d, i, o, u, x, X 変換のことである。
hh 整数変換に対応する引た瑤 signed char か unsigned char で、 n
変換に対応する引た瑤 signed char へのポインタであることを示す。
h 整数変換に対応する引た瑤 short int か unsigned short int で、 n
変換に対応する引た瑤 short int へのポインタであることを示す。
l (エル)
各変換に対応する引た瑤、 整数変換では long intか unsigned long
int、 n 変換では long long int へのポインタ、 c 変換では
wint_t、 s 変換では wchar_t へのポインタであることを示す。
ll (エルエル)
整数変換に対応する引た瑤 long long int か unsigned long long
int で、 n 変換に対応する引た瑤 long int
へのポインタであることを示す。
L a, A, e, E, f, F, g, G 変換に対応する引た瑤 long double
であることを示す。 (C99 では %LF を使うことを認めているが、SUSv2
では認められていない。)
q (`quad'。 4.4BSD と Linux libc5 のみ邑。使ってはならない。) ll
と同じ意味である。
j 整数変換に対応する引た瑤 intmax_t か uintmax_t
であることを示す。
z 整数変換に対応する引た瑤 size_t か ssize_t であることを示す。
(Linux libc5 では、これを指定するのに Z
を用いる。使ってはならない。)
t 整数変換に対応する引た瑤 ptrdiff_t であることを示す。
SUSv2 で長さ修飾子として使用でい襪里蓮 h (hd, hi, ho, hx, hX, hn), l
(ld, li, lo, lx, lX, ln, lc, ls), L (Le, LE, Lf, Lg, LG) だけである。
変儡換校指慊定蟷子
適用される変換の型を指定する文字。
変換指定子とその意味は以下の通りである。
d,i int 引た瑤鯢箙翩佞 10 進表気吠儡垢垢襦
精度指定があれば、精度で指定した桁数は必ず出力される。変換後の値が
指定された桁数に造蠅覆ぞ豺腓蓮∈限Δ 0 で埋められる。
デフォルトの精度は 1 である。 0
を表示しようとした時に、明示的に精度として 0
が指定されていると、 出力は空文字列となる。
o,u,x,X
unsigned int 引た瑤髻 符号なし8進数 (o), 符号なし10進数 (u),
符号なし16進数 (x と X) に変換する。 x 変換では abcdef
が使用され、 X 変換では ABCDEF が使用される。
精度指定があれば、精度で指定した桁数は必ず出力される。変換後の値が
指定された桁数に造蠅覆ぞ豺腓蓮∈限Δ 0 で埋められる。
e,E double 引た瑤魎櫃瓩 [-]d.ddde+-dd の形に変換する。
小数点の前には一桁の数字があり、小数点以下の桁数は精度で指定された
桁数になる。精度は指定されなかった場合 6 とみなされる。 精度が 0
の場合には、小数点以下は表示されない。 E
変換では、指数を表現するとい (e ではなく) E が使われる。
指数部分は少なくとも 2桁表示される。 つまり、指数の値が 0
の場合には、00 と表示される。
f,F double 引た瑤魎櫃瓩 [-]ddd.ddd の形の10進表現に変換する。
小数点の後の桁数は、精度で指定された値となる。
精度が指定されていない場合には 6 として扱われる。
精度として明示的に 0 が指定されたと-
には、小数点以下は表示されない。
小数点を表示する際には、小数点の前に少なくとも一桁は数字が表示される。
(SUSv2 では、 F は規定されておらず、無限や NaN
に関する文字列表現を 行ってもよいことになっている。
C99 標準では、 f 変換では、無限は `[-]inf' か `[-]infinity'
と表示し、 NaN は文字列の先頭に `nan'
をつけて表示するように規定されている。 F 変換の場合は `[-]INF',
`[-]INFINITY', `NAN*' と表示される。)
g,G double 引た瑤 f か e (G 変換の場合は F か E) の形式に変換する。
精度は表示する桁数を指定する。
精度が指定されない場合は、6桁とみなされる。 精度が 0
の場合は、1桁とみなされる。 変換される値の指数が、 -4
より小さいか、精度以上の場合に、 e 形式が使用される。
変換された結果の小数部分の末尾の 0
は削除される。小数点が表示されるのは、
小数点以下に数字が少なくとも一つある場合にだけである。
a,A (C99 にはあるが SUSv2 にはない) a 変換では、 double 引た瑤
(abcdef の文字を使って) [-]0xh.hhhhp+-d; 形式の 16 進表-
に変換する。 A 変換では、前置文字列 0X, 文字 ABCDEF, 指数文字 P
を用いる。 小数点の前には
1桁の16進数が置かれ、小数点の後ろの桁数は
精度で指定された値となる。 デフォルトの精度は、その値が
2進数で正確に表現でい訃豺腓砲蓮 その値を正確に表現で-
る桁数となる。それ以外の場合は、 double
型の値を区別するのに十分な大い気箸覆襦
小数点の前の数字は、正規化されていない数の場合はいくつになるか分からない。
正規化された数の場合は、 0
以外の値になるが、いくつになるかは分からない。
c l 修飾子がなければ、 int 引た瑤 unsigned char
に変換して、その結果に対応する文字を出力する。 l
修飾子があれば、 wint_t (ワイド文字) 引た瑤髻 wcrtomb()
関数を初期シフト状態で呼び出してマルチバイト文字列に変換し、
変換されたマルチバイト文字列を出力する。
s l 修飾子がない場合、 引た瑤 const char *
型で文字型の配列へのポインタ (文字列へのポインタ) であることが
期待されている。配列中の文字は、終端の NULL バイト ('\0')
が出てくるまで出力される (終端文字は出力されない)。
精度が指定されていると、指定された字数以上は出力されない。
精度が指定された場合には、終端バイトが存在する必要はない。
精度が指定されていなかったり、精度の値が配列の大い気茲蠡腓-
い場合には、 配列は終端の NULL
バイトを含んでいなければならない。
l 修飾子が指定されている場合、 引た瑤 const wchar_t *
型でワイド文字の配列へのポインタであることが期待されている。
配列中のワイド文字は (1文字毎に wcrtomb() を呼び出して)
マルチバイト文字に変換される (最初のワイド文字の変換の前に wcr-
tomb() のシフト状態を初期状態に戻してから変換は行われる)。
マルチバイト文字への変換は、文字列を終端する NULL ワイド文字が
出てくるまで行われ、終端 NULL ワイド文字も含めて変換される。
結果のマルチバイト文字列は、終端の NULL バイトが出てくるまで
出力される (終端の NULL バイトは出力されない)。
精度が指定された場合、指定されたバイト数以上には出力されない。
但し、マルチバイト文字の一部分だけが出力されることはない。
精度は「バイト」数を指定するものであり、「ワイド文字」数や
「画面での位置」を指定するものではないことに注意。
精度が指定されていて、さらに出力が配列の末尾に達する前に出力バイト数が
精度の値を超える場合だけは、配列は NULL
ワイド文字で終端されていなくてもよい。
それ以外の場合は、必ず配列は NULL
ワイド文字で終端されていなければならない。
C (C99 にはないが SUSv2 にはある) lc と同じ。使ってはならない。
S (C99 にはないが SUSv2 にはある) ls と同じ。使ってはならない。
p void * ポインタ引た瑤 (%#x や %#lx のような) 16
進数で出力する。
n これまでに出力された文字数を int * (または類似の型)
のポインタ引た瑤指す整数に保存する。 引た瑤諒儡垢蝋圓錣譴覆ぁ
m (glibc での拡張) strerror(errno) の出力を表示する。引-
数は必要ない。
% `%' 文字を出力する。変換される引た瑤鰐気ぁ 変換指定全体を書くと
`%%' となる。
pi を 5 桁で出力する。
#include <math.h>
#include <stdio.h>
fprintf(stdout, "pi = %.5f\n", 4 * atan(1.0));
日付と時間を `Sunday, July 3, 10:02' の形式で出力する。 (weekday と
month は文字列へのポインタである)
#include <stdio.h>
fprintf(stdout, "%s, %s %d, %.2d:%.2d\n",
weekday, month, day, hour, min);
日 - 月 - 年 の順序で表示を行う国も多い。
従って、国際版では書式で指定された順番で 引た瑤鯢充┐任-
なければならない。
#include <stdio.h>
fprintf(stdout, format,
weekday, month, day, hour, min);
format はロケールに依存しており、引た瑤僚臠屬鯤僂┐襪海箸發任る。 for-
mat が
"%1$s, %3$d. %2$s, %4$d:%5$.2d\n"
であれば、 `Sonntag, 3. Juli, 10:02' という結果になる。
十分に大い癖源列領域を確保して、そこにメッセージを格納するには (glibc
2.0 と glibc 2.1 の両方で正しく動作するコード):
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
char *
make_message(const char *fmt, ...) {
/* Guess we need no more than 100 bytes. */
int n, size = 100;
char *p, *np;
va_list ap;
if ((p = malloc (size)) == NULL)
return NULL;
while (1) {
/* Try to print in the allocated space. */
va_start(ap, fmt);
n = vsnprintf (p, size, fmt, ap);
va_end(ap);
/* If that worked, return the string. */
if (n > -1 && n < size)
return p;
/* Else try again with more space. */
if (n > -1) /* glibc 2.1 */
size = n+1; /* precisely what is needed */
else /* glibc 2.0 */
size *= 2; /* twice the old size */
if ((np = realloc (p, size)) == NULL) {
free(p);
return NULL;
} else {
p = np;
}
}
}
glibc の snprintf() と vsnprintf() の実装は、バージョン 2.1 以降は C99
標準に準拠しており、 上気猟未蠅瞭虻遒鬚垢襦 glibc 2.0.6
までは、出力が切り詰められた場合は -1 を返す。
fprintf(), printf(), sprintf(), vprintf(), vfprintf(), vsprintf()
関数は、C89 と C99 に準拠している。 snprintf() と vsnprintf() は C99
に準拠している。
snprintf() の返り値を見ると、 SUSv2 と C99 標準は互いに矛盾している。
SUSv2 では、 snprintf() が size=0 で呼び出された場合、 1
未満の値を何か返り値とするように規定している。 一方 C99
では、このような場合 str を NULL とし、返り値として (通常通り)
出力バッファが十分な大い気
あった場合に出力されるであろう文字数を返す。
Linux libc4 では、 5 つの C 標準のフラグ、 長さ修飾子 h, l, L 、変換
cdeEfFgGinopsuxX が使える。 但し F は f と同じである。 また、 D, O, U
を ld, lo, lu と同じものとして使える (これはまずい仕様で、 後に %D
の対応が打ち切られた時に深刻なバグを 引-
起こした)。ロケール依存の小数点、1000 区切り、 NaN と無限、 %m$ と *m$
は使えない。
Linux libc5 では、 5 つの C 標準のフラグと ' フラグ、ロケール、 %m$ と
*m$ が使える。 また、長さ修飾子 h, l, L, Z, q が使えるが、 L と q
は両方とも long double と long long integer に対応している
(これはバグである)。 現在では FDOU 変換は認識されないが、変換文字 m
が追加された。これは strerror(errno) を出力するものである。
glibc 2.0 では、変換文字 C と S が追加された。
glibc 2.1 では、長さ修飾子 hh, j, t, z と変換文字 a, A が追加された。
glibc 2.2 では、 C99 で規定された意味での変換文字 F と フラグ文字 I
が追加された。
Unix V7 では printf(), fprintf(), sprintf() の 3 つの関数と、フラグ
-、幅と精度での *、長さ修飾子 l、 変換 doxfegcsu、そして ld,ld,lu,lx
の同義語として D,O,U,X が定義されている。 2.9.1BSD
でもこれは同じだったが、 2.10BSD では フラグ #, +, 空白が追加され、
D,O,U,X については戯椶気譴覆なった。 2.11BSD では vprintf(),
vfprintf(), vsprintf() が追加され、 D,O,U,X
を使わないように警告された。 4.3BSD Reno ではフラグ 0、長さ修飾子 h と
L、 変換 n, p, E, G, (現在の意味での) X が追加され、 D,O,U
は非推奨扱いとなった。 4.4BSD では、関数 snprintf()と vsnprintf()、
長さ修飾子 q が導入された。 FreeBSD では、 sprintf()
のために十分なバッファを確保する asprintf() と vasprintf()
が追加されている。 glibc には、関数 dprintf(), vdprintf()
があり、これらはストリームではなくファイルディスクリプタに出力する。
sprintf() と vsprintf()
は勝手に十分に長い文字列領域があると仮定するので、呼び出し側は
実際の領域からあふれないように注意しなければならない。
しかし、これを保証することが不可能な場合が多い。
生成される文字列の長さはロケール依存であり、予測が難しいことに注意。
代わりに snprintf() と vsnprintf() (または asprintf() と vasprintf())
を使うこと。
Linux libc4.[45] には snprintf() はないが、 libbsd が提供されており、
その中には sprintf() と等価な (つまり size 引た瑤鯡技襪垢) snprintf()
がある。 したがって、初期の libc4 で snprintf() を使うと、深刻なセ-
ュリティ問題を引さこすことがある。
printf(foo); のようなコードはしばしばバグを引さこす。 なぜなら foo に
% 文字が含まれてるかもしれないからである。 foo が信頼で-
ないユーザー入力から作られている場合には、 その中に %n
が含まれていることがあり、 printf() 呼び出し時にメモリへの書-
込みが起こり、 セゥ絅螢謄ーホールを作ることになるかもしれない。
printf(1), asprintf(3), dprintf(3), scanf(3), setlocale(3), wcrtomb(3),
wprintf(3), locale(5)
Linux Manpage 16 October 2000 PRINTF(3)