snprintf
, _snprintf
, _snprintf_l
, _snwprintf
, _snwprintf_l
文字列に書式付きデータを書き込みます。 これらの関数のセキュリティを強化したバージョンを使用できます。「_snprintf_s
、_snprintf_s_l
、_snwprintf_s
、_snwprintf_s_l
」を参照してください。
構文
int snprintf(
char *buffer,
size_t count,
const char *format [,
argument] ...
);
int _snprintf(
char *buffer,
size_t count,
const char *format [,
argument] ...
);
int _snprintf_l(
char *buffer,
size_t count,
const char *format,
_locale_t locale [,
argument] ...
);
int _snwprintf(
wchar_t *buffer,
size_t count,
const wchar_t *format [,
argument] ...
);
int _snwprintf_l(
wchar_t *buffer,
size_t count,
const wchar_t *format,
_locale_t locale [,
argument] ...
);
template <size_t size>
int _snprintf(
char (&buffer)[size],
size_t count,
const char *format [,
argument] ...
); // C++ only
template <size_t size>
int _snprintf_l(
char (&buffer)[size],
size_t count,
const char *format,
_locale_t locale [,
argument] ...
); // C++ only
template <size_t size>
int _snwprintf(
wchar_t (&buffer)[size],
size_t count,
const wchar_t *format [,
argument] ...
); // C++ only
template <size_t size>
int _snwprintf_l(
wchar_t (&buffer)[size],
size_t count,
const wchar_t *format,
_locale_t locale [,
argument] ...
); // C++ only
パラメーター
buffer
出力の格納場所。
count
書き込む最大文字数。 受け取る wchar_t
関数の場合、書き込むワイド文字の最大数です。
format
書式指定文字列。
argument
省略可能な引数。
locale
出力の書式設定に使用するロケール。
詳細については、「書式指定の構文: printf
およびwprintf
関数」を参照してください。
戻り値
無視された場合 count
にバッファーに書き込まれた文字数。 カウントには終了 NULL
文字は含まれません。
終了NULL
を含めず、書式設定されたデータ文字列の長さを指定しますlen
。
すべての関数に対してlen
、文字が格納されているbuffer
場合len < count
は、null ターミネータが追加され、終端NULL
文字を含まない書き込まれた文字数が返されます。
これらの関数のワイド文字バージョンは、終端文字を含まない、書き込まれたワイド文字の数を NULL
返します。
詳細については、 動作の概要 を参照してください。
解説
Visual Studio 2015 および Windows 10 で UCRT と共に開始する場合、 snprintf
は _snprintf
と同一ではなくなります。 動作が snprintf
C99 標準に準拠するようになりました。 違いは、バッファーが不足した場合、バッファーの末尾を null で終了し、 snprintf
必要な文字数を返すのに対し _snprintf
、バッファーを null 終了せず、-1 を返すことです。 また、バッファーを null で終了しないため、 snprintf()
出力にもう 1 つの文字を含めます。
snprintf
と関数ファミリは_snprintf
、書式を設定し、count
格納する文字の数をbuffer
減らします。snprintf
は常に終端文字を格納しNULL
、必要に応じて出力を切り捨てます。- 値 >
count
- 1 が返された場合snprintf
、出力は切り捨てられました。 _snprintf
書式設定された文字列の長さが厳密に文字よりcount
小さい場合、関数ファミリは終了NULL
文字のみを追加します。- 各
argument
(指定されている場合) は、format
中の対応する書式指定に応じて変換され、格納されます。 書式は通常の文字で構成され、その形式と機能はprintf
のformat
引数と同じです。 重なり合う文字列間でコピーした場合の動作は未定義です。
動作の概要
次の表の場合:
- のサイズ
buffer
にしましょうsizeOfBuffer
。 関数がバッファーをchar
受け取る場合、サイズはバイト単位です。 関数がバッファーをwchar_t
受け取る場合、サイズは 16 ビットワードの数を指定します。 - 書式設定されたデータのサイズを指定します
len
。 関数がバッファーをchar
受け取る場合、サイズはバイト単位です。 関数がバッファーをwchar_t
受け取る場合、サイズは 16 ビットワードの数を指定します。 - 文字は、バッファーを
char
受け取る関数の文字と、バッファーをwchar_t
受け取char
るwchar_t
関数の文字を指します。 - 無効なパラメーター ハンドラーの詳細については、「パラメーターの検証」を参照してください。
状態 | 動作 | 戻り値 | errno |
無効なパラメーター ハンドラーを呼び出す |
---|---|---|---|---|
Success | 指定した書式指定文字列を使用して、バッファーに文字を書き込みます。 | 書き込まれる文字数です。 | 該当なし | いいえ |
書式設定中のエンコード エラー | 文字列指定子 s 、 S または Z 書式指定の処理が停止した場合、a NULL はバッファーの先頭に配置されます。 |
-1 | EILSEQ (42) |
いいえ |
書式設定中のエンコード エラー | 文字指定子またはC 文字指定子c を処理する場合、無効な文字はスキップされます。 書き込まれた文字数は、スキップされた文字に対してインクリメントされず、データも書き込まれません。 書式指定の処理は、エンコード エラーで指定子をスキップした後も続行されます。 |
終わる NULL 文字を含まない、書き込まれた文字数。 |
EILSEQ (42) |
いいえ |
buffer == NULL および count != 0 |
無効なパラメーター ハンドラーの実行後も実行が続行される場合は、負の値を設定 errno して返します。 |
-1 | EINVAL (22) |
はい |
count == 0 |
終了 NULL 文字を含まない、書き込まれた文字数。 この結果を使用して、文字列と終端に十分なバッファー領域を NULL 割り当て、関数を再度呼び出してバッファーを埋めることができます。 |
該当なし | いいえ | |
count < 0 |
Unsafe: 値は符号なしとして扱われ、バッファーに続くメモリが上書きされる大きな値が作成される可能性があります。 | 書き込まれた文字数 | 該当なし | いいえ |
count < sizeOfBuffer および len <= count |
すべてのデータが書き込まれ、終了 NULL が追加されます。 |
終わる NULL 文字を含まない、書き込まれた文字数。 |
該当なし | いいえ |
count < sizeOfBuffer および len > count |
最初 count-1 の文字の後に null 終端記号が書き込まれます。 |
書き込まれた文字数が、null ターミネータを含めずに出力する文字数と一致していました 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
」を参照してください。
重要
format
にユーザー定義の文字列を指定しないでください。 _snprintf
関数では null で終わることが保証されないため (特に戻り値が count
の場合)、これらの関数の後に、終端の null を追加するコードが続いていることを確認してください。 詳細については、「バッファー オーバーランの回避」を参照してください。
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
にリンクします。
_snwprintf
は _snprintf
のワイド文字バージョンであり、 _snwprintf
のポインター引数はワイド文字列です。 エンコード エラーの検出は、次の _snwprintf
検出 _snprintf
とは異なる場合があります。 _snwprintf
と同様に、 swprintf
では出力が FILE
型の出力先ではなく文字列に書き込まれます。
これらの関数のうち _l
サフィックスが付けられたバージョンは、現在のスレッド ロケールの代わりに渡されたロケール パラメーターを使用する点を除いて同じです。
C++ では、これらの関数には、より新しい、より安全な対応する関数を呼び出すテンプレート オーバーロードがあります。 詳細については、「セキュリティで保護されたテンプレート オーバーロード」を参照してください。
汎用テキスト ルーチンのマップ
Tchar.h ルーチン |
_UNICODE と _MBCS が定義されていない |
_MBCS が定義されている |
_UNICODE が定義されている |
---|---|---|---|
_sntprintf |
_snprintf |
_snprintf |
_snwprintf |
_sntprintf_l |
_snprintf_l |
_snprintf_l |
_snwprintf_l |
必要条件
ルーチンによって返される値 | 必須ヘッダー |
---|---|
snprintf , _snprintf , _snprintf_l |
<stdio.h> |
_snwprintf , _snwprintf_l |
<stdio.h> または <wchar.h> |
互換性の詳細については、「 Compatibility」を参照してください。
例
// crt_snprintf.c
// compile with: /W3
#include <stdio.h>
#include <stdlib.h>
#if !defined(__cplusplus)
typedef int bool;
const bool true = 1;
const bool false = 0;
#endif
#define FAIL 0 // change to 1 and see what happens
int main(void)
{
char buffer[200];
const static char s[] = "computer"
#if FAIL
"computercomputercomputercomputercomputercomputercomputercomputer"
"computercomputercomputercomputercomputercomputercomputercomputer"
"computercomputercomputercomputercomputercomputercomputercomputer"
"computercomputercomputercomputercomputercomputercomputercomputer"
#endif
;
const char c = 'l';
const int i = 35;
#if FAIL
const double fp = 1e300; // doesn't fit in the buffer
#else
const double fp = 1.7320534;
#endif
/* !subtract one to prevent "squeezing out" the terminal null! */
const int bufferSize = sizeof(buffer)/sizeof(buffer[0]) - 1;
int bufferUsed = 0;
int bufferLeft = bufferSize - bufferUsed;
bool bSuccess = true;
buffer[0] = 0;
/* Format and print various data: */
if (bufferLeft > 0)
{
int perElementBufferUsed = _snprintf(&buffer[bufferUsed],
bufferLeft, " String: %s\n", s ); // C4996
// Note: _snprintf is deprecated; consider _snprintf_s instead
if (bSuccess = (perElementBufferUsed >= 0))
{
bufferUsed += perElementBufferUsed;
bufferLeft -= perElementBufferUsed;
if (bufferLeft > 0)
{
int perElementBufferUsed = _snprintf(&buffer[bufferUsed],
bufferLeft, " Character: %c\n", c ); // C4996
if (bSuccess = (perElementBufferUsed >= 0))
{
bufferUsed += perElementBufferUsed;
bufferLeft -= perElementBufferUsed;
if (bufferLeft > 0)
{
int perElementBufferUsed = _snprintf(&buffer
[bufferUsed], bufferLeft, " Integer: %d\n", i ); // C4996
if (bSuccess = (perElementBufferUsed >= 0))
{
bufferUsed += perElementBufferUsed;
bufferLeft -= perElementBufferUsed;
if (bufferLeft > 0)
{
int perElementBufferUsed = _snprintf(&buffer
[bufferUsed], bufferLeft, " Real: %f\n", fp ); // C4996
if (bSuccess = (perElementBufferUsed >= 0))
{
bufferUsed += perElementBufferUsed;
}
}
}
}
}
}
}
}
if (!bSuccess)
{
printf("%s\n", "failure");
}
else
{
/* !store null because _snprintf doesn't necessarily (if the string
* fits without the terminal null, but not with it)!
* bufferUsed might be as large as bufferSize, which normally is
* like going one element beyond a buffer, but in this case
* subtracted one from bufferSize, so we're ok.
*/
buffer[bufferUsed] = 0;
printf( "Output:\n%s\ncharacter count = %d\n", buffer, bufferUsed );
}
return EXIT_SUCCESS;
}
Output:
String: computer
Character: l
Integer: 35
Real: 1.732053
character count = 69
関連項目
ストリーム入出力
sprintf
, _sprintf_l
, swprintf
, _swprintf_l
, __swprintf_l
fprintf
, _fprintf_l
, fwprintf
, _fwprintf_l
printf
, _printf_l
, wprintf
, _wprintf_l
scanf
, _scanf_l
, wscanf
, _wscanf_l
sscanf
, _sscanf_l
, swscanf
, _swscanf_l
vprintf
関数
フィードバック
https://aka.ms/ContentUserFeedback」を参照してください。
以下は間もなく提供いたします。2024 年を通じて、コンテンツのフィードバック メカニズムとして GitHub の issue を段階的に廃止し、新しいフィードバック システムに置き換えます。 詳細については、「フィードバックの送信と表示