日本語 man コマンド類 (ja-man-1.1j_5) と日本語 man ドキュメント (ja-man-doc-5.4 (5.4-RELEASE 用) など) をインストールすると、以下のような man コマンド閲覧、キーワード検索が コンソールからできるようになります。
4.11-RELEASE-K, 5.4-RELEASE-K, 5.5-RELEASE-K, 6.0-RELEASE-K から 6.4-RELEASE-K, 7.0-RELEASE-K から 7.4-RELEASE-K, 8.0-RELEASE-K から 8.4-RELEASE-K, 9.0-RELEASE-K から 9.3-RELEASE-K, 10.0-RELEASE-K から 10.3-RELEASE-K, 11.0-RELEASE-K から 11.4-RELEASE-K, 12.0-RELEASE-K, 12.1-RELEASE-K は、 プライベート版 (小金丸が編集してまとめたもの) ですが、 より多くの翻訳したファイルが含まれています。 (5.4-RELEASE-K から 6.4-RELEASE-K, 7.0-RELEASE-K から 7.4-RELEASE-K, 8.0-RELEASE-K から 8.4-RELEASE-K, 9.0-RELEASE-K から 9.3-RELEASE-K, 10.0-RELEASE-K から 10.3-RELEASE-K, 11.0-RELEASE-K から 11.4-RELEASE-K, 12.0-RELEASE-K から 12.4-RELEASE-K, 13.0-RELEASE-K から 13.3-RELEASE-K, 14.0-RELEASE-K から 14.1-RELEASE-K は、全翻訳済み)
13.3-STABLE-K, 15.0-CURRENT-K は現在、作成中で日々更新されています。
Table of Contents
PRINTF(3) FreeBSD ライブラリ関数マニュアル PRINTF(3)
名称
printf, fprintf, sprintf, snprintf, asprintf, dprintf, vprintf, vfprintf,
vsprintf, vsnprintf, vasprintf, vdprintf -- 書式化された出力の変換
ライブラリ
標準 C ライブラリ (libc, -lc)
書式
#include <stdio.h>
int
printf(const char * restrict format, ...);
int
fprintf(FILE * restrict stream, const char * restrict format, ...);
int
sprintf(char * restrict str, const char * restrict format, ...);
int
snprintf(char * restrict str, size_t size, const char * restrict format,
...);
int
asprintf(char **ret, const char *format, ...);
int
dprintf(int fd, const char * restrict format, ...);
#include <stdarg.h>
int
vprintf(const char * restrict format, va_list ap);
int
vfprintf(FILE * restrict stream, const char * restrict format,
va_list ap);
int
vsprintf(char * restrict str, const char * restrict format, va_list ap);
int
vsnprintf(char * restrict str, size_t size, const char * restrict format,
va_list ap);
int
vasprintf(char **ret, const char *format, va_list ap);
int
vdprintf(int fd, const char * restrict format, va_list ap);
解説
printf() 関数ファミリは、下記に説明するように format にしたがって出力を生
成します。printf() と vprintf() 関数は、標準出力ストリーム stdout に出力
を書き込みます。fprintf() と vfprintf() は、与えられた出力ストリーム
stream に出力を書き込みます。dprintf() と vdprintf() は、与えられたファイ
ル記述子に出力を書き込みます。sprintf(), snprintf(), vsprintf() と
vsnprintf() は、文字列 str に出力を書き込みます。そして asprintf() と
vasprintf() は、malloc(3) で新しい文字列を動的に割り付けます。
これらの関数は、後に続く引数 (または stdarg(3) の可変長引数機能によってア
クセスできる引数) が出力のためにどのように変換するかを指定する、format 文
字列の制御に従って出力を書き込みます。
asprintf() と vasprintf() 関数は、書式化された文字列を保存するために十分
大きなバッファへのポインタとなるように、*ret を設定します。このポインタ
は、もはや必要でなくなったときに、割り付けられた記憶域を解放するために
free(3) に渡されるべきです。十分な空間を割り付けることができないなら、
asprintf() と vasprintf() は、-1 を返し、NULL ポインタとなるように ret を
設定します。
snprintf() と vsnprintf() 関数は、出力文字列 (そして size 番目の文字は、
終端の `\0' になります) に印刷された多くても size-1 文字を書き込みます。
返り値が size 引数以上であるなら、文字列は、短かすぎ、印刷された文字の一
部は、破棄されます。出力は、size が 0 でないなら、常にヌル文字で終了しま
す。
sprintf() と vsprintf() 関数は、事実上 INT_MAX + 1 の size であると仮定し
ます。
書式文字列は、0 以上のディレクティブ (指示) から構成されています: 出力ス
トリームに変更されずにコピーされる、通常文字 (% 以外)。そして、それぞれの
変換指定は、0 以上の後続の引数を取って来る結果となります。各変換指定は、%
文字で導入されます。引数は、(タイプ促進の後に) 変換指示子で適切に対応しな
ければなりません。% の後は、次のシーケンスで現れます。
• アクセスする次の引数を指定して、$ が続いている 10 進数の文字列から成
るオプションのフィールド。このフィールドが提供されないなら、アクセス
される最後の引数に続いている引数が使用されます。引数は、1 で始まる番
号を付けられます。書式文字列のアクセスされない引数が、アクセスされる
ものに組み入れられているなら、結果は、不定です。
• 次のフラグの 0 以上は、次の通りです:
`#' 値は、``alternate form'' (代替形式) に変換されるべきで
す。c, d, i, n, p, s と u 変換について、このオプションに
は、効果がありません。o 変換について、数値の精度は、出力
文字列の最初の文字を 0 に強制するために増加されます。x
と X 変換について、0 でない結果は、それの前に `0x' (また
は、X 変換のために `0X') があります。a, A, e, E, f, F,
g, と G 変換について、結果は、たとえ数字がそれに続かなく
ても、常に小数点を含みます (通常、小数点は、数字が続いて
いる場合のみ、それらの変換の結果に現れます)。g と G 変換
について、後続する 0 は、そうでなければ、それらのよう
に、結果から取り除かれません。
`0' (zero) 0 のパディング。n を除いて、すべての変換について、変換さ
れた値は、空白でなく、0 で左側にパディングされます。精度
が数値変換 (d, i, o, u, i, x と X) で与えられるなら、0
フラグは、無視されます。
`-' 負のフィールド幅のフラグ。変換された値は、フィールド境界
で左に調整されます。n 変換を除いて、変換された値は、空白
または 0 で左側でなく、空白で右側にパディングされます。-
と 0 の両方が与えられるなら、- は、0 を上書きします。
` ' (空白) 空白は、符号付き変換 (a, A, d, e, E, f, F, g, G または
i) によって生成される正の数値の前に残されるべきです。
`+' 符号は、数値が符号付き変換によって生成されるされる前に、
常に置かれなければなりません。両方が使用されるなら、+
は、空白を上書きします。
`'' (アポストロフィ)
10 進数の変換 (d, u または i) または浮動小数点の変換 (f
または F) の整数部 (integral portion) は、localeconv(3)
によって返された非通貨のセパレータを使用して数千単位でグ
ループ化され、分離されるべきです。
• 最小のフィールド幅を指定しているオプションの 10 進数の文字列。変換さ
れた値がフィールド幅より少ない文字であるなら、それは、フィールド幅を
書き込むために左に (または左揃えフラグが、与えられるなら、右に) 空白
でパディングされます。
• オプションの数字文字列が続いているピリオド . の形式のオプションの精
度。数字文字列が省略されるなら、精度は、0 になります。これは、d, i,
o, u, x と X 変換のために現れる最小の桁の数、a, A, e, E, f と F 変換
のための小数点の後に現れる桁の数、g と G 変換のための最大の有効桁の
数、または s 変換のための文字列から印刷 (表示) される最大の文字数を与
えます。
• 引数のサイズを指定するオプションの長さ修飾子。次の長さ修飾子は、d, i,
n, o, u, x または X 変換のために有効です:
修飾子 d, i o, u, x, X n
hh signed char unsigned char signed char *
h short unsigned short short *
l (エル) long unsigned long long *
ll (エルエル) long long unsigned long long long long *
j intmax_t uintmax_t intmax_t *
t ptrdiff_t (注参照) ptrdiff_t *
z (注参照) size_t (注参照)
q (非推奨) quad_t u_quad_t quad_t *
注: t 修飾子は、o, u, x または X 変換に適用されるとき、引数がサイズで
unsigned タイプと ptrdiff_t が同等であることを示します。z 修飾子は、d
または i 変換に適用されるとき、引数がサイズで signed タイプと size_t
が同等であることを示します。同様に、n 変換に適用されるとき、それは、
引数がサイズで signed タイプへのポインタと size_t が同等であることを
示します。
次の長さ修飾子 a, A, e, E, f, F, g または G 変換で有効です:
修飾子 a, A, e, E, f, F, g, G
l (エル) double (無視されます、それ以外は、同じ振る舞い)
L long double
次の長さ修飾子 c または s 変換で有効です:
修飾子 c s
l (エル) wint_t wchar_t *
• 適用される変換のタイプを指定する文字。
フィールド幅または精度、または両方は、アスタリスク `*'、または数字文字列
の代わりに 1 つ以上の 10 進数と `$' が続いているアスタリスクによって示さ
れます。この場合に、int 引数は、フィールド幅または精度を供給します。負の
フィールド幅は、正のフィールド幅が続いている左揃えのフラグとして扱われま
す。負な精度は、あたかもそれが失われたかのように扱われます。単一の書式
ディレクティブが、ポジション (nn$) とポジションなしの引数と混じっているな
ら、結果は、未定義です。
変換指示子とそれらの意味は、次の通りです:
diouxX int (または適切な変異型) 引数は、符号付き 10 進数 (d と i)、符号
無し 8 進数 (o)、符号無し 10 進数 (u)、符号無し 16 進数 (x と X)
記法に変換されます。文字 ``abcdef'' は、x 変換のために使用されま
す。文字 ``ABCDEF'' は、X 変換のために使用されます。精度は、もし
あるなら、現れなければならない最小の数値の桁を与えます。変換され
た値が少ない桁を要求するなら、左を 0 で詰められます。
DOU long int 引数は、あたかも書式がそれぞれ ld, lo または lu であった
かのように、符号付き 10 進数、符号無し 8 進数、または符号無し 10
進数に変換されます。これらの変換文字は、非推奨であり、最終的にな
くなるでしょう。
eE double 引数は、丸められ、スタイル [-]d.ddde+-dd に変換されます、
ここで、小数点文字の前に 1 桁、その後の桁の数は、精度と等しくなり
ます。精度が不足しているなら、それは、6 とされます。精度が 0 であ
るなら、小数点文字は、現れません。E 変換は、指数を導入するために
(`e' ではなく) 文字 `E' を使用します。指数は、少なくとも 2 桁を常
に含んでいます。値が 0 であるなら、指数は、00 です。
a, A, e, E, f, F, g, と G 変換について、正と負の無限は、小文字の
変換文字を使用するとき、それぞれ inf と -inf として表され、大文字
の変換文字を使用するとき、それぞれ INF と -INF として表されます。
同様に、NaN は、小文字の変換を使用するとき、nan として表され、大
文字の変換を使用するとき、NAN として表されます。
fF double 引数は、丸められ、スタイル [-]ddd.ddd の 10 進数の表記に変
換されます、ここで、小数点文字の後の桁の数は、精度の指定と等しく
なります。精度が不足しているなら、それは、6 とされます。精度が明
示的に 0 であるなら、小数点文字は、現れません。小数点が現れるな
ら、少なくとも 1 桁が、その前に現れます。
gG double 引数は、スタイル f または e (または G 変換のための F また
は E) で変換されます。精度は、有効な桁数を指定します。精度が不足
しているなら、6 桁が与えられます。精度が 0 であるなら、それは、1
として扱われます。スタイル e は、その変換からの指数が -4 未満であ
るか、または精度以上であるなら、使用されます。後続する 0 は、結果
の小数部分から取り除かれます。小数点は、少なくとも 1 桁が続く場合
のみ、現れます。
aA double 引数は、丸められ、スタイル [-]0xh.hhhp[+-]d, の 16 進数の
記法に変換されます、ここで、16 進数ポイント文字の後の桁の数は、精
度の指定と等しくなります。精度が不足しているなら、それは、浮動小
数点数を正確に表すのに十分となるように取られ、丸めるは、起こりま
せん。精度が 0 であるなら、16 進数ポイント文字は、現れません。p
は、リテラル文字 `p' であり、指数は、2 の指数を表している 10 進数
が続いている正または負の符号から成ます。A 変換は、16 進数を表すた
めに接頭辞 (``0x'' ではなく) ``0X''、文字 (``abcdef'' ではなく)
``ABCDEF'' を使用し、仮数と指数を分離するために文字 (`p' ではな
く) `P' を使用します。
この 16 進数の形式で浮動小数点数を表すために複数の有効な方法があ
ることに注意してください。例えば、0x1.92p+1, 0x3.24p+0, 0x6.48p-1
と 0xc.9p-2 は、すべて同等です。FreeBSD 8.0 以降は、常に、16 進数
ポイントの前の桁として `1' を使用して有限の非 0 の数値を印刷 (表
示) します。0 は、常に、(適切であるなら、`-' によって先導される)
0 の仮数と +0 の指数で表されます。
C l (エル) 修飾子で c として扱われます。
c int 引数は、unsigned char に変換され、結果の文字が、書き込まれま
す。
l (エル) 修飾子が使用されるなら、wint_t 引数は、wchar_t に変換さ
れるものとして、単一のワイド文字を表している (潜在的にマルチバイ
トの) シーケンスは、あらゆるシフトシーケンスを含んで、書き込まれ
ます。シフトシーケンスが使用されるなら、シフト状態は、また、文字
の後のオリジナルの状態に復元されます。
S l (エル) 修飾子で s として扱われます。
s char * 引数は、文字タイプの配列へのポインタ (文字列へのポインタ)
であることが期待されます。配列の文字は、終端のヌル文字まで (しか
し含まずに) 書き込まれます。精度が指定されるなら、指定された数以
上は、書き込まれません。精度が与えられるなら、ヌル文字は、存在す
る必要はありません。精度が指定されないか、または配列のサイズより
大きいなら、配列は、終端のヌル文字を含んでいなければなりません。
l (エル) 修飾子が使用されるなら、wchar_t * は、ワイド文字の配列へ
のポインタ (ワイド文字列へのポインタ) であることが期待されます。
文字列のワイド文字ごとに、ワイド文字を表している (潜在的にマルチ
バイトの) シーケンスは、あらゆるシフトシーケンスを含んで、書き込
まれます。あらゆるシフトシーケンスが使用されるなら、シフト状態
は、また、文字列の後のオリジナルの状態に復元されます。配列のワイ
ド文字は、終端のワイドヌル文字まで (しかし含まずに) 書き込まれま
す。精度が指定されるなら、指定されたバイトの数だけ (シフトシーケ
ンスを含んで) 書き込まれます。部分的な文字は、決して書き込まれま
せん。精度が与えられるなら、ヌル文字は、存在する必要はありませ
ん。精度が指定されないか、または文字列のマルチバイト表現を与える
ために必要なバイトの数より大きいなら、配列は、終端のワイドヌル文
字を含んでいなければなりません。
p void * ポインタ引数は、(あたかも `%#x' または `%#lx' が指定された
かのように) 16 進数で印刷 (表示) されます。
n これまでに書き込まれた文字数は、int * (または変異型) ポインタ引数
によって示された整数に格納されます。引数は、変換されません。
m strerror(3) によって返されるように、呼び出しの始めで、errno 変数
に格納されたエラーコードの文字列表現を印刷 (表示) します。引数
は、取られません。
% `%' は、書き込まれます。引数は、変換されません。完全な変換指定
は、`%%' です。
小数点文字は、プログラムのロケール (カテゴリ LC_NUMERIC) で定義されます。
どんな場合にも、存在しないか、または小さいフィールド幅は、数値フィールド
の切り捨てを引き起こします。変換の結果がフィールド幅より広いなら、フィー
ルドは、変換結果を含むように拡張されます。
戻り値
これらの関数は、size が (最後の `\0' を含まずに) 無限であったなら、印刷
(表示) された文字数を返す snprintf() と vsnprintf() を除いて、(文字列への
出力を終るために使用される後続する `\0' を含まずに) 印刷 (表示) された文
字数を返します。これらの関数は、エラーが起こるなら、負の値を返します。
使用例
形式 ``Sunday, July 3, 10:02'' で日付と時刻を印刷 (表示) するためには、次
の通りです、ここで、weekday と month は、文字列へのポインタです:
#include <stdio.h>
fprintf(stdout, "%s, %s %d, %.2d:%.2d\n",
weekday, month, day, hour, min);
小数第 5 位まで pi を印刷 (表示) するためには、次の通りです:
#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);
}
互換性
変換形式 %D, %O と %U は、標準ではなく、後方互換性のためだけに提供されて
います。また、変換形式 %m は、標準でなく、GNU C ライブラリからよく知られ
ている拡張を提供しています。
%p 形式を (0 フラグまたは精度を指定するかのいずれかで) 0 をパディングする
効果と %n と %p 変換で # フラグの良性の効果 (つまりなし) は、%Ld のような
他の無意味な組み合わせと同様に標準ではありません。そのような組み合わせは
避けられるべきです。
エラー
write(2) システムコールのためにドキュメント化されたエラーに加えて、
printf() ファミリ関数は、次の場合に失敗します:
[EILSEQ] 無効のワイド文字コードに遭遇しました。
[ENOMEM] 利用可能な記憶域空間が不足しています。
[EOVERFLOW] size 引数が INT_MAX + 1 を越えているか、または、返り値
が、int によって表せるものより大きすぎます。
関連項目
printf(1), errno(2), fmtcheck(3), scanf(3), setlocale(3), strerror(3),
wprintf(3)
規格
下記のバグセッションで注意された警告を前提として、fprintf(), printf(),
sprintf(), vprintf(), vfprintf() と vsprintf() 関数は、ANSI X3.159-1999
(``ANSI C89'') と ISO/IEC 9899:1999 (``ISO C99'') に適合しています。同じ
条件で、snprintf() と vsnprintf() 関数は、ISO/IEC 9899:1999 (``ISO C99'')
に適合しています、一方 dprintf() と vdprintf() は、IEEE Std 1003.1-2008
(``POSIX.1'') に適合しています。
歴史
関数 asprintf() と vasprintf() は、GNU C ライブラリではじめて登場しまし
た。これらは、FreeBSD 2.2 で Peter Wemm <peter@FreeBSD.org> によって実装
されましたが、その後 Todd C. Miller <Todd.Miller@courtesan.com> によって
OpenBSD 2.3 から異なった実装で置き換えられました。dprintf() と vdprintf()
関数は、FreeBSD 8.0 で追加されました。%m 形式の拡張は、GNU C ライブラリで
はじめて登場し、FreeBSD 12.0 で実装されました。
バグ
printf 関数ファミリは、format 引数で正しくマルチバイト文字を取り扱いませ
ん。
セキュリティの考察
sprintf() と vsprintf() 関数は、悪意があるユーザがバッファオーバフロー攻
撃で実行プログラムの機能性を任意に変更することを可能にする方法で容易に悪
用されます。sprintf() と vsprintf() は、無限に長い文字列を仮定するので、
呼び出し側は、実際の空間をオーバフローしないように注意しなければなりませ
ん。保証することはしばしば困難です。安全のために、プログラマは、
snprintf() インタフェースを代わりに使用するべきです。例えば:
void
foo(const char *arbitrary_string, const char *and_another)
{
char onstack[8];
#ifdef BAD
/*
* この最初の sprintf は悪い振る舞いです。sprintf を使用しなこと!
*/
sprintf(onstack, "%s, %s", arbitrary_string, and_another);
#else
/*
* 次の 2 つの行は、snprintf() のより良い使用例です。
*
*/
snprintf(onstack, sizeof(onstack), "%s, %s", arbitrary_string,
and_another);
#endif
}
printf() と sprintf() 関数ファミリは、``スタックの上に残された'' 潜在的な
機密のデータを印刷するのを引き起こすか、または無効のポインタの修飾参照に
よってメモリフォルトかバスエラーを発生させるのを引き起こすかのいずれかに
よって悪意があるユーザが任意に実行プログラムの機能性を変更する方法で容易
に悪用されます。
潜在的に慎重に選択されたアドレスに任意のデータを書き込むために %n を使用
することができます。したがって、プログラマは、format 引数として、攻撃者が
可能性のあるセキュリティホールの原因となる、利用者のスタックを台なしにす
る文字列で書式記述子を置くことができるような、信頼されていない文字列を決
して渡さないように強く勧められます。結果として作成される文字列にまだ
printf() によって後の挿入のためにユーザによって供給された変換指示子を含ん
でいるとき、文字列が snprintf() のような関数を使用することで構築されたと
しても、このホールは、当てはまります。
常に適切で安全な慣用法を使用してください:
snprintf(buffer, sizeof(buffer), "%s", string);
FreeBSD 13.2 May 22, 2018 FreeBSD 13.2