コンテンツにスキップ

printf

出典: フリー百科事典『ウィキペディア(Wikipedia)』

これはこのページの過去の版です。Takawata (会話 | 投稿記録) による 2024年6月23日 (日) 00:45個人設定で未設定ならUTC)時点の版 (→‎長さ修飾子)であり、現在の版とは大きく異なる場合があります。


printfC (stdio.h)  (stdout) JIS X 3010:2003printfstdoutfprintf (7.19.6.3)

1C12int

形式

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

書式化文字列


%0%


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

 (POSIX)


CPOSIX

%%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 型または wchar_t 型または double 型[3] wchar_t についてはC95以降、double についてはC99以降
ll(エルエル) 実引数は long long 型 C99以降
j 実引数は intmax_t 型 C99以降
z 実引数は size_t 型 C99以降
t 実引数は ptrdiff_t 型 C99以降
L 実引数は long double 型 全バージョン

なお、この引数型はデータ型モデルによってint32_tなどのビット数が指定される型に対して移植の際に64ビットアーキテクチャと32ビットアーキテクチャでは非互換が生じることがある。これに対応するためには、明示的な型キャストや、inttypes.hヘッダに定義されるPRIで始まるマクロを利用する。

変換指定子

指定子 意味 導入バージョン
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


sprintfsnprintfcharstrstrsnprintfstrCC99
#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に対応し、ワイド文字を使用するものである。sprintfに対応するワイド文字関数(出力バッファサイズを受け取らない関数)は存在しない[4]

#include <stdio.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を付けた名称となっている。

#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);
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);

安全性を向上させたもの


C11Annex K Boundschecking 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書式の禁止

Windows API

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

// 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*typedefWUnicodeAANSIMBCSUnicodeUNICODEWAwsprintfwnsprintf

floatdoubleC/C++C (CRT) Windows使使<strsafe.h>使[7]

Windows API_stdcall__stdcallWINAPI / STDAPICALLTYPE...API_cdecl__cdeclWINAPIV / STDAPIVCALLTYPEx86

コード例

#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[8]Visual C++CRT%n使[9]

Cprintf()


CC++DPHP[10]Ruby[11]PerlprintfPython 2.xprint3.xprint

Ruby[12]Python%使sprintfBoost C++Boost.Format[13]boost::format%[14]

C++20std::format()[15]C++23std::print()[16]

UnixprintfBashUnix

Java


Java 1.5Stringformat()java.io.PrintStreamformat()printf()


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

JavaObjectintdoublejava.util.IllegalFormatExceptionjava.util.MissingFormatArgumentException

Java使printf()

脚注



(一)^ gettext

(二)^ Windows APIFormatMessage()Microsoft Foundation ClassAfxFormatString2().NET FrameworkSystem.String.Format()

(三)^ floatdoubledouble

(四)^ Microsoft Visual C++swprintf2005 (8.0) sprintfswprintf (CRT) | Microsoft Docs, sprintf, _sprintf_l, swprintf, _swprintf_l, __swprintf_l | Microsoft Docs

(五)^ wsprintfA function (winuser.h) - Win32 apps | Microsoft Learn

(六)^ wnsprintfA function (shlwapi.h) - Win32 apps | Microsoft Learn

(七)^ 使 - Windows drivers | Microsoft Learn

(八)^ 10  . IPA ISEC C/C++.   . 201273

(九)^ Format Specification Syntax: `printf` and `wprintf` Functions | Microsoft Learn

(十)^ PHP: printf. PHP (2013322). 2013328

(11)^ Kernel.#printf. Ruby 1.9.3 . 2013328

(12)^ Instance method String#%. Ruby 1.9.3 . 2013328

(13)^ The Boost Format Library (2006122). 2013328

(14)^  - boostjp

(15)^ format - cpprefjp C++

(16)^ print - cpprefjp C++

参考文献

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

関連項目

外部リンク