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
格納する最大文字数。

format
書式指定文字列。

argument
省略可能な引数。

locale
使用するロケール。

詳細については、「書式指定構文: printf および wprintf 関数」を参照してください。

戻り値

以下の説明では、書式付きデータ文字列の長さ (終端の null は含まない) を len とします。 snprintf_snprintf の場合、lencount はどちらも文字数で、_snwprintf の場合は、ワイド文字数です。

すべての関数について、 len<countの場合、 len の文字数が bufferに格納されて、終端の null が追加され、 len が返されます。

snprintf 関数は、 lencount以上の場合、null 終端記号を buffer[count-1]に配置することによって、出力を切り捨てます。 戻り値は lenです。 count のサイズが十分な場合に出力されたであろう文字数です。 snprintf 関数は、エンコード エラーが発生すると負の値を返します。

snprintf を除くすべての関数について、len = count の場合、len の文字数が buffer に格納されて、終端の null は追加されず、len が返されます。 len>count の場合、count の文字数が buffer に格納されて、終端の null は追加されずに、負の値が返されます。

buffer が null ポインターで count がゼロの場合、 len は、出力の書式を指定するのに必要な文字数として返されます。終端の null は含まれません。 同じ argument パラメーターおよび locale パラメーターを指定して正常な呼び出しを行うには、少なくとも len + 1 文字を保持するバッファーを割り当てます。

buffer が Null ポインターで count が 0 以外の場合、または format が Null ポインターの場合は、「パラメーターの検証」に説明されているように、正しくないパラメーター ハンドラーが呼び出されます。 実行の継続が許可された場合、これらの関数は -1 を返し、 errnoEINVALに設定します。

これらのエラー コードおよびその他のエラー コードについては、「errno_doserrno_sys_errlist, and _sys_nerr」を参照してください。

解説

snprintf 関数と、関数の _snprintf ファミリは、 count 以下の文字数を書式指定し、 bufferに格納します。 snprintf 関数は、常に終端の null 文字を格納し、必要に応じて出力を切り捨てます。 関数の _snprintf ファミリは、書式付き文字列の長さが確実に count 文字数未満の場合にのみ、終端の null 文字を追加します。 各 argument (指定されている場合) は、 format中の対応する書式指定に応じて変換され、格納されます。 書式は通常の文字で構成され、その形式と機能は printfformat 引数と同じです。 重なり合う文字列間でコピーした場合の動作は未定義です。

重要

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 にリンクします。

Visual Studio 2015 および Windows 10 で UCRT と共に開始する場合、 snprintf_snprintfと同一ではなくなります。 snprintf 関数の動作は、現在 C99 標準準拠です。

_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 関数