Share via


_snprintf_s, _snprintf_s_l, _snwprintf_s, _snwprintf_s_l

Menulis data yang diformat ke string. Fungsi-fungsi ini adalah versi snprintf, , _snprintf_snprintf_l, _snwprintf, _snwprintf_l dengan peningkatan keamanan yang dijelaskan dalam Fitur keamanan di CRT.

Sintaks

int _snprintf_s(
   char *buffer,
   size_t sizeOfBuffer,
   size_t count,
   const char *format [,
   argument] ...
);

int _snprintf_s_l(
   char *buffer,
   size_t sizeOfBuffer,
   size_t count,
   const char *format,
   _locale_t locale [,
   argument] ...
);

int _snwprintf_s(
   wchar_t *buffer,
   size_t sizeOfBuffer,
   size_t count,
   const wchar_t *format [,
   argument] ...
);

int _snwprintf_s_l(
   wchar_t *buffer,
   size_t sizeOfBuffer,
   size_t count,
   const wchar_t *format,
   _locale_t locale [,
   argument] ...
);

template <size_t size>
int _snprintf_s(
   char (&buffer)[size],
   size_t count,
   const char *format [,
   argument] ...
); // C++ only

template <size_t size>
int _snwprintf_s(
   wchar_t (&buffer)[size],
   size_t count,
   const wchar_t *format [,
   argument] ...
); // C++ only

Parameter

buffer
Lokasi penyimpanan untuk output.

sizeOfBuffer
Ukuran lokasi penyimpanan untuk output. Ukuran dalam byte untuk fungsi yang mengambil char, dan kata-kata untuk mereka yang mengambil wchar_t.

count
Jumlah karakter maksimum yang akan ditulis. Untuk fungsi yang mengambil wchar_t, ini adalah jumlah maksimum karakter lebar untuk ditulis. Atau _TRUNCATE.

format
String kontrol format.

argument
Argumen opsional.

locale
Lokal yang akan digunakan.

Nilai hasil

Jumlah karakter yang ditulis, tidak termasuk yang mengakhiri NULL. Nilai negatif dikembalikan jika terjadi kesalahan output. Lihat Ringkasan perilaku untuk detailnya.

Keterangan

Fungsi _snprintf_s memformat dan menyimpan count atau lebih sedikit karakter dalam buffer dan menambahkan penghentian NULL. Setiap argumen (jika ada) dikonversi dan output sesuai dengan spesifikasi format yang sesuai di format. Pemformatan konsisten dengan printf keluarga fungsi; lihat Sintaks spesifikasi format: printf dan wprintf fungsi. Jika penyalinan terjadi di antara string yang tumpang tindih, perilaku tidak terdefinisi.

Ringkasan perilaku

Untuk tabel berikut:

-Biarkan len menjadi ukuran data yang diformat. Jika fungsi mengambil char buffer, ukurannya dalam byte. Jika fungsi mengambil wchar_t buffer, ukuran menentukan jumlah kata 16-bit.

  • Karakter merujuk ke char karakter untuk fungsi yang mengambil char buffer, dan ke wchar_t karakter untuk fungsi yang mengambil wchar_t buffer.
  • Untuk informasi selengkapnya tentang handler parameter yang tidak valid, lihat Validasi Parameter.
Kondisi Perilaku Nilai hasil errno Memanggil handler parameter yang tidak valid
Sukses Menulis karakter ke dalam buffer menggunakan string format yang ditentukan. Jumlah karakter yang ditulis, tidak termasuk yang mengakhiri NULL. T/A Tidak
Kesalahan pengodean selama pemformatan Jika pemrosesan penentu sstring , , Satau Z, pemrosesan spesifikasi format berhenti. -1 EILSEQ (42) Tidak
Kesalahan pengodean selama pemformatan Jika memproses penentu c karakter atau C, karakter yang tidak valid dilewati. Jumlah karakter yang ditulis tidak bertahap untuk karakter yang dilewati, atau data apa pun yang ditulis untuknya. Memproses spesifikasi format berlanjut setelah melewati penentu dengan kesalahan pengodean. Jumlah karakter yang ditulis, tidak termasuk yang mengakhiri NULL. EILSEQ (42) Tidak
buffer == NULLdan dan sizeOfBuffer == 0count == 0 Tidak ada data yang ditulis. 0 T/A Tidak
buffer == NULLdan atau sizeOfBuffer != 0count != 0 Jika eksekusi berlanjut setelah handler parameter tidak valid dijalankan, set errno dan mengembalikan nilai negatif. -1 EINVAL (22) Ya
buffer != NULL dan sizeOfBuffer == 0 Tidak ada data yang ditulis. -1 EINVAL (22) Ya
count == 0 ditempatkan NULL di awal buffer. -1 T/A Tidak
count < 0 Tidak aman: nilai diperlakukan sebagai tidak ditandatangani, kemungkinan menciptakan nilai besar yang menghasilkan penimpaan memori yang mengikuti buffer. Jumlah karakter yang ditulis, tidak termasuk yang mengakhiri NULL. T/A Tidak
count < sizeOfBuffer dan len <= count Semua data ditulis dan penghentian NULL ditambahkan. Jumlah karakter yang ditulis. T/A Tidak
count < sizeOfBuffer dan len > count Karakter pertama count ditulis dan penghentian NULL ditambahkan. -1 T/A Tidak
count >= sizeOfBuffer dan len < sizeOfBuffer Semua data ditulis dengan penghentian NULL. Jumlah karakter yang ditulis. T/A Tidak
count >= sizeOfBufferdan dan len >= sizeOfBuffercount != _TRUNCATE Jika eksekusi berlanjut setelah handler parameter tidak valid dijalankan, set errno, set buffer[0] == NULL, dan mengembalikan nilai negatif. -1 ERANGE (34) Ya
count == _TRUNCATE dan len >= sizeOfBuffer Menulis sebanyak string yang sesuai buffer dan mengakhiri NULL. -1 T/A Tidak
count == _TRUNCATE dan len < sizeOfBuffer Menulis seluruh string ke dalam buffer dengan mengakhiri NULL. Jumlah karakter yang ditulis, tidak termasuk yang mengakhiri NULL. T/A Tidak
format == NULL Tidak ada data yang ditulis. Jika eksekusi berlanjut setelah handler parameter tidak valid dijalankan, set errno dan mengembalikan nilai negatif. -1 EINVAL (22) Ya

Untuk informasi tentang kode kesalahan ini dan lainnya, lihat _doserrno, , errno_sys_errlist, dan _sys_nerr.

Penting

Pastikan itu format bukan string yang ditentukan pengguna.

Mulai Windows 10 versi 2004 (build 19041), printf keluarga fungsi mencetak angka titik mengambang yang persis dapat diwakili sesuai dengan aturan IEEE 754 untuk pembulatan. Di versi Windows sebelumnya, angka titik pecahan yang persis dapat diwakili yang berakhiran '5' akan selalu dibulatkan. IEEE 754 menyatakan bahwa mereka harus membulatkan ke digit terdekat bahkan (juga dikenal sebagai "Pembulatan Bankir"). Misalnya, dan printf("%1.0f", 1.5)printf("%1.0f", 2.5) harus membulatkan ke 2. Sebelumnya, 1,5 akan membulatkan ke 2 dan 2,5 akan dibulatkan ke 3. Perubahan ini hanya memengaruhi angka yang tepat yang dapat diwakili. Misalnya, 2,35 (yang, ketika diwakili dalam memori, lebih dekat ke 2,3500000000000000008) terus membulatkan ke atas hingga 2,4. Pembulatan yang dilakukan oleh fungsi-fungsi ini sekarang juga menghormati mode pembulatan titik mengambang yang ditetapkan oleh fesetround. Sebelumnya, pembulatan selalu memilih FE_TONEAREST perilaku. Perubahan ini hanya memengaruhi program yang dibuat menggunakan Visual Studio 2019 versi 16.2 dan yang lebih baru. Untuk menggunakan perilaku pembulatan titik mengambang warisan, tautkan dengan 'legacy_stdio_float_rounding.obj'.

_snwprintf_s adalah versi _snprintf_skarakter lebar ; argumen penunjuk untuk _snwprintf_s adalah string karakter lebar. Deteksi kesalahan pengodean mungkin berbeda dari yang ada di _snwprintf_s_snprintf_s. _snwprintf_s, seperti swprintf_s, menulis output ke string daripada ke tujuan jenis FILE.

Versi fungsi-fungsi ini dengan _l akhiran identik kecuali mereka menggunakan parameter lokal yang diteruskan alih-alih lokal utas saat ini.

Di C++, menggunakan fungsi-fungsi ini disederhanakan oleh kelebihan beban templat; kelebihan beban dapat menyimpulkan panjang buffer secara otomatis (menghilangkan kebutuhan untuk menentukan argumen ukuran) dan mereka dapat secara otomatis mengganti fungsi lama yang tidak aman dengan rekan-rekan yang lebih baru dan aman. Untuk informasi selengkapnya, lihat Mengamankan kelebihan beban templat.

Pemetaan rutin teks generik

Tchar.h Rutin _UNICODE dan _MBCS tidak ditentukan _MBCS Didefinisikan _UNICODE Didefinisikan
_sntprintf_s _snprintf_s _snprintf_s _snwprintf_s
_sntprintf_s_l _snprintf_s_l _snprintf_s_l _snwprintf_s_l

Persyaratan

Rutin Header yang diperlukan
_snprintf_s, _snprintf_s_l <stdio.h>
_snwprintf_s, _snwprintf_s_l <stdio.h> atau <wchar.h>

Untuk informasi kompatibilitas selengkapnya, lihat Kompatibilitas.

Contoh

// crt_snprintf_s.cpp
// compile with: /MTd

// These #defines enable secure template overloads
// (see last part of Examples() below)
#define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES 1
#define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_COUNT 1

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <crtdbg.h>  // For _CrtSetReportMode
#include <errno.h>

// This example uses a 10-byte destination buffer.

int snprintf_s_tester( const char * fmt, int x, size_t count )
{
   char dest[10];

   printf( "\n" );

   if ( count == _TRUNCATE )
      printf( "%zd-byte buffer; truncation semantics\n",
               _countof(dest) );
   else
      printf( "count = %zd; %zd-byte buffer\n",
               count, _countof(dest) );

   int ret = _snprintf_s( dest, _countof(dest), count, fmt, x );

   printf( "    new contents of dest: '%s'\n", dest );

   return ret;
}

void Examples()
{
   // formatted output string is 9 characters long: "<<<123>>>"
   snprintf_s_tester( "<<<%d>>>", 121, 8 );
   snprintf_s_tester( "<<<%d>>>", 121, 9 );
   snprintf_s_tester( "<<<%d>>>", 121, 10 );

   printf( "\nDestination buffer too small:\n" );

   snprintf_s_tester( "<<<%d>>>", 1221, 10 );

   printf( "\nTruncation examples:\n" );

   int ret = snprintf_s_tester( "<<<%d>>>", 1221, _TRUNCATE );
   printf( "    truncation %s occur\n", ret == -1 ? "did"
                                                  : "did not" );

   ret = snprintf_s_tester( "<<<%d>>>", 121, _TRUNCATE );
   printf( "    truncation %s occur\n", ret == -1 ? "did"
                                                  : "did not" );
   printf( "\nSecure template overload example:\n" );

   char dest[10];
   _snprintf( dest, 10, "<<<%d>>>", 12321 );
   // With secure template overloads enabled (see #defines
   // at top of file), the preceding line is replaced by
   //    _snprintf_s( dest, _countof(dest), 10, "<<<%d>>>", 12345 );
   // Instead of causing a buffer overrun, _snprintf_s invokes
   // the invalid parameter handler.
   // If secure template overloads were disabled, _snprintf would
   // write 10 characters and overrun the dest buffer.
   printf( "    new contents of dest: '%s'\n", dest );
}

void myInvalidParameterHandler(
   const wchar_t* expression,
   const wchar_t* function,
   const wchar_t* file,
   unsigned int line,
   uintptr_t pReserved)
{
   wprintf(L"Invalid parameter handler invoked: %s\n", expression);
}

int main( void )
{
   _invalid_parameter_handler oldHandler, newHandler;

   newHandler = myInvalidParameterHandler;
   oldHandler = _set_invalid_parameter_handler(newHandler);
   // Disable the message box for assertions.
   _CrtSetReportMode(_CRT_ASSERT, 0);

   Examples();
}

count = 8; 10-byte buffer
    new contents of dest: '<<<121>>'

count = 9; 10-byte buffer
    new contents of dest: '<<<121>>>'

count = 10; 10-byte buffer
    new contents of dest: '<<<121>>>'

Destination buffer too small:

count = 10; 10-byte buffer
Invalid parameter handler invoked: ("Buffer too small", 0)
    new contents of dest: ''

Truncation examples:

10-byte buffer; truncation semantics
    new contents of dest: '<<<1221>>'
    truncation did occur

10-byte buffer; truncation semantics
    new contents of dest: '<<<121>>>'
    truncation did not occur

Secure template overload example:
Invalid parameter handler invoked: ("Buffer too small", 0)
    new contents of dest: ''

Baca juga

Streaming I/O
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 Fungsi