引数のリストへのポインタを使用して、書式設定された出力を書き込みます。 これらの関数のより安全なバージョンが利用可能です。 vsnprintf_s
、 _vsnprintf_s
、 _vsnprintf_s_l
、 _vsnwprintf_s
、 _vsnwprintf_s_l
を参照してください。
構文
int vsnprintf(
char *buffer,
size_t count,
const char *format,
va_list argptr
);
int _vsnprintf(
char *buffer,
size_t count,
const char *format,
va_list argptr
);
int _vsnprintf_l(
char *buffer,
size_t count,
const char *format,
_locale_t locale,
va_list argptr
);
int _vsnwprintf(
wchar_t *buffer,
size_t count,
const wchar_t *format,
va_list argptr
);
int _vsnwprintf_l(
wchar_t *buffer,
size_t count,
const wchar_t *format,
_locale_t locale,
va_list argptr
);
template <size_t size>
int vsnprintf(
char (&buffer)[size],
size_t count,
const char *format,
va_list argptr
); // C++ only
template <size_t size>
int _vsnprintf(
char (&buffer)[size],
size_t count,
const char *format,
va_list argptr
); // C++ only
template <size_t size>
int _vsnprintf_l(
char (&buffer)[size],
size_t count,
const char *format,
_locale_t locale,
va_list argptr
); // C++ only
template <size_t size>
int _vsnwprintf(
wchar_t (&buffer)[size],
size_t count,
const wchar_t *format,
va_list argptr
); // C++ only
template <size_t size>
int _vsnwprintf_l(
wchar_t (&buffer)[size],
size_t count,
const wchar_t *format,
_locale_t locale,
va_list argptr
); // C++ only
パラメーター
buffer
出力の保存場所。
count
書き込む最大文字数。
wchar_t
を必要とする関数の場合、書き込むワイド文字の数です。
format
フォーマット仕様。
argptr
引数のリストへのポインタ。
locale
使用するロケール。
詳細については、「 形式指定の構文」を参照してください。
戻り値
書き込まれた文字数 (終端 NULL
を含まない)、または出力エラーが発生した場合は負の値。
詳細については、 Behavior の概要 を参照してください。
注釈
これらの各関数は、引数リストへのポインターを受け取り、データを書式設定し、buffer
が指すメモリに最大 count
文字を書き込みます。
vsnprintf
関数は、出力が切り捨てられる場合でも、常に null ターミネータを書き込みます。
_vsnprintf
と _vsnwprintf
を使用すると、末尾に余裕がある場合 (つまり、書き込む文字数が count
未満の場合) にのみ、バッファーが null で終了します。
Visual Studio 2015 および Windows 10 で UCRT と共に開始する場合、 vsnprintf
は _vsnprintf
と同一ではなくなります。
vsnprintf
関数は C99 標準に準拠しています。_vsnprintf
は、古いコードとの下位互換性のために保持されています。 違いは、バッファが不足すると、 vsnprintf
はバッファの末尾を null で終了して必要な文字数を返すのに対し、 _vsnprintf
はバッファを null で終了せず、-1 を返すことです。 また、 _vsnprintf()
では、バッファーが null で終了しないため、出力にもう 1 文字が含まれます。
Von Bedeutung
特定の種類のセキュリティ リスクを防ぐには、 format
がユーザー定義の文字列でないことを確認します。 詳細については、「バッファー オーバーランの回避」を参照してください。
Windows 10 バージョン 2004 (ビルド 19041) 以降の printf
ファミリの関数では、丸め処理の IEEE 754 の規則に従って、正確に表現可能な浮動小数点数が出力されます。 以前のバージョンの Windows では、"5" で終わる正確に表現可能な浮動小数点数は常に切り上げられていました。 IEEE 754 では、最も近い偶数に丸める ("銀行型丸め" とも呼ばれます) 必要があることが示されています。 たとえば、printf("%1.0f", 1.5)
と printf("%1.0f", 2.5)
の両方を 2 に丸める必要があります。 以前は、1.5 は 2 に、2.5 は 3 に丸められていました。 この変更は、正確に表現可能な数値にのみ影響します。 たとえば、2.35 (メモリで表される場合は 2.35000000000000008 に近い) は、2.4 に切り上げられます。 これらの関数によって実行される丸め処理では、fesetround
によって設定された浮動小数点丸めモードにも従うようになりました。 以前は、丸め処理には常に FE_TONEAREST
の動作が選択されていました。 この変更は、Visual Studio 2019 バージョン 16.2 以降を使用してビルドされたプログラムにのみ影響します。 従来の浮動小数点丸め動作を使用するには、 'legacy_stdio_float_rounding.obj' でリンクします。
注
_vsnprintf
、_vsnprintf_l
、_vsnwprintf
、_vsnwprintf_l
を呼び出すときに終了 null の余地を確保するには、count
がバッファーの長さより厳密に小さいことを確認し、関数を呼び出す前にバッファーを null に初期化します。
vsnprintf
は常に終端の null を書き込むため、count
パラメーターはバッファーのサイズと等しくなる場合があります。
これらの関数のサフィックスが _l
であるバージョンは、現在のスレッド ロケールの代わりに渡された locale パラメーターを使用する点を除いて同じです。
C++ では、これらの関数には、これらの関数の新しく安全な対応物を呼び出すテンプレート オーバーロードがあります。 詳細については、「セキュリティ保護されたテンプレート オーバーロード」を参照してください。
動作の概要
次の表について、次のようにします。
-
sizeOfBuffer
をbuffer
のサイズとします。 関数がchar
バッファを取る場合、サイズはバイト単位です。 関数がwchar_t
バッファーを受け取る場合、サイズは 16 ビット ワードの数を指定します。 -
len
フォーマットされたデータのサイズとします。 関数がchar
バッファを取る場合、サイズはバイト単位です。 関数がwchar_t
バッファーを受け取る場合、サイズは 16 ビット ワードの数を指定します。 - 文字とは、
char
バッファーを受け取る関数のchar
文字と、wchar_t
バッファーを受け取る関数のwchar_t
文字を指します。 - 無効なパラメータハンドラの詳細については、「 パラメータの検証」を参照してください。
条件 | 行動 | 戻り値 | errno |
無効なパラメータハンドラを呼び出します |
---|---|---|---|---|
成功 | 指定した書式指定文字列を使用して、文字をバッファーに書き込みます。 | 書き込まれた文字数 (終端の null 文字は含みません)。 | なし | いいえ |
フォーマット中のエンコードエラー | 文字列指定子の処理が s 、 S 、または Z の場合、書式指定の処理は停止します。 |
-1 |
EILSEQ (42) |
いいえ |
フォーマット中のエンコードエラー | 文字指定子が c または C を処理する場合、無効な文字はスキップされます。 スキップされた文字に対して書き込まれる文字数は増加せず、データも書き込まれません。 フォーマット指定の処理は、エンコード・エラーで指定子をスキップした後も続行されます。 |
書き込まれた文字数 (終端の NULL は含まれません)。 |
EILSEQ (42) |
いいえ |
buffer == NULL と count != 0 |
無効なパラメータハンドラの実行後に実行が続行される場合は、 errno を設定し、負の値を返します。 |
-1 |
EINVAL (22) |
イエス |
buffer == NULL と count == 0 |
データは書き込まれません | 書き込まれるはずだった文字数 (終端の NULL は含みません)。 この結果を使用して、文字列と終了 NULL に十分なバッファー領域を割り当て、関数を再度呼び出してバッファーを埋めることができます。 |
なし | いいえ |
count == 0 |
データは書き込まれません | -1 |
ERANGE (34) |
いいえ |
count < 0 |
安全でない: 値は符号なしとして扱われ、大きな値が作成される可能性があり、その結果、バッファに続くメモリが上書きされます。 | 書き込まれる文字数。 | なし | いいえ |
count < sizeOfBuffer と len <= count |
すべてのデータが書き込まれ、終了 NULL が追加されます。 |
書き込まれた文字数 (終端の NULL は含まれません)。 |
なし | いいえ |
count < sizeOfBuffer と len > count |
最初の count-1 文字は記述され、その後にヌル終端記号が続きます。 |
count 出力する文字数と一致していれば書き込まれるはずだった文字数 (ヌル終端記号は含まれません)。 |
なし | いいえ |
count >= sizeOfBuffer と len < sizeOfBuffer |
すべてのデータは、終了 NULL で書き込まれます。 |
書き込まれた文字数 (終端の NULL は含まれません)。 |
なし | いいえ |
count >= sizeOfBuffer と len >= sizeOfBuffer |
Unsafe: バッファに続くメモリを上書きします。 | 書き込まれた文字数 (終端の NULL は含まれません)。 |
なし | いいえ |
format == NULL |
データは書き込みされません。 無効なパラメータハンドラの実行後に実行が続行される場合は、 errno を設定し、負の値を返します。 |
-1 |
EINVAL (22) |
イエス |
これらのエラー コードおよびその他のエラー コードの詳細については、「_doserrno
、errno
、_sys_errlist
、_sys_nerr
」を参照してください。
汎用テキスト ルーチンのマップ
TCHAR.H ルーチン |
_UNICODE と _MBCS が定義されていない |
_MBCS が定義されている |
_UNICODE が定義されている |
---|---|---|---|
_vsntprintf |
_vsnprintf |
_vsnprintf |
_vsnwprintf |
_vsntprintf_l |
_vsnprintf_l |
_vsnprintf_l |
_vsnwprintf_l |
要求事項
ルーチンによって返される値 | 必須ヘッダー (C) | 必須ヘッダー (C++) |
---|---|---|
vsnprintf 、 _vsnprintf 、 _vsnprintf_l |
<stdio.h> |
<stdio.h> または <cstdio> |
_vsnwprintf 、_vsnwprintf_l |
<stdio.h> または <wchar.h> |
<stdio.h> 、<wchar.h> 、<cstdio> 、または <cwchar> |
_vsnprintf
、_vsnprintf_l
、_vsnwprintf
、_vsnwprintf_l
の各機能は Microsoft 固有です。 互換性の詳細については、「 互換性」を参照してください。
例: ワイド文字を _vsnwprintf()
// crt_vsnwprintf.c
// compile by using: cl /W3 crt_vsnwprintf.c
// To turn off error C4996, define this symbol:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <wtypes.h>
#define BUFFCOUNT (10)
void FormatOutput(LPCWSTR formatstring, ...)
{
int nSize = 0;
wchar_t buff[BUFFCOUNT];
memset(buff, 0, sizeof(buff));
va_list args;
va_start(args, formatstring);
// Note: _vsnwprintf is deprecated; consider vsnwprintf_s instead
nSize = _vsnwprintf(buff, BUFFCOUNT - 1, formatstring, args); // C4996
wprintf(L"nSize: %d, buff: %ls\n", nSize, buff);
va_end(args);
}
int main() {
FormatOutput(L"%ls %ls", L"Hi", L"there");
FormatOutput(L"%ls %ls", L"Hi", L"there!");
FormatOutput(L"%ls %ls", L"Hi", L"there!!");
}
nSize: 8, buff: Hi there
nSize: 9, buff: Hi there!
nSize: -1, buff: Hi there!
代わりに vsnprintf をナロー文字列パラメータと共に使用すると、動作が変わります。
count
パラメーターはバッファーの全体のサイズにすることができ、戻り値は、count
十分に大きかった場合に書き込まれる文字数です。
例: vsnprintf()
を狭い文字列で使用する
// crt_vsnprintf.c
// compile by using: cl /W4 crt_vsnprintf.c
#include <stdio.h>
#include <stdarg.h> // for va_list, va_start
#include <string.h> // for memset
#define BUFFCOUNT (10)
void FormatOutput(char* formatstring, ...)
{
int nSize = 0;
char buff[BUFFCOUNT];
memset(buff, 0, sizeof(buff));
va_list args;
va_start(args, formatstring);
nSize = vsnprintf(buff, sizeof(buff), formatstring, args);
printf("nSize: %d, buff: %s\n", nSize, buff);
va_end(args);
}
int main() {
FormatOutput("%s %s", "Hi", "there"); // 8 chars + null
FormatOutput("%s %s", "Hi", "there!"); // 9 chars + null
FormatOutput("%s %s", "Hi", "there!!"); // 10 chars + null
}
nSize: 8, buff: Hi there
nSize: 9, buff: Hi there!
nSize: 10, buff: Hi there!
こちらも参照ください
ストリーム入出力
vprintf
関数
形式指定構文: printf
関数と wprintf
関数
fprintf
、 _fprintf_l
、 fwprintf
、 _fwprintf_l
printf
、 _printf_l
、 wprintf
、 _wprintf_l
sprintf
、 _sprintf_l
、 swprintf
、 _swprintf_l
、 __swprintf_l
va_arg
、 va_copy
、 va_end
、 va_start