snprintf
, , _snprintf
_snprintf_l
, , _snwprintf
,_snwprintf_l
Menulis data yang diformat ke string. Versi yang lebih aman dari fungsi-fungsi ini tersedia; lihat _snprintf_s
, _snprintf_s_l
, _snwprintf_s
, . _snwprintf_s_l
Sintaks
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
Parameter
buffer
Lokasi penyimpanan untuk output.
count
Jumlah karakter maksimum yang akan ditulis. Untuk fungsi yang mengambil wchar_t
, ini adalah jumlah maksimum karakter lebar untuk ditulis.
format
String kontrol format.
argument
Argumen opsional.
locale
Lokal yang digunakan untuk memformat output.
Untuk informasi selengkapnya, lihat Sintaks spesifikasi format: printf
dan wprintf
fungsi.
Nilai hasil
Jumlah karakter yang akan ditulis ke buffer jika count
diabaikan. Jumlah tidak menyertakan karakter yang mengakhiri NULL
.
Biarkan len
panjang string data yang diformat, tidak termasuk penghentian NULL
.
Untuk semua fungsi, jika len < count
, maka len
karakter disimpan dalam buffer
, terminator null ditambahkan, dan jumlah karakter yang ditulis, tidak termasuk penghentian NULL
, dikembalikan.
Versi karakter yang luas dari fungsi-fungsi ini mengembalikan jumlah karakter lebar yang ditulis, tidak termasuk yang mengakhiri NULL
.
Lihat Ringkasan perilaku untuk detailnya.
Keterangan
Dimulai dengan UCRT di Visual Studio 2015 dan Windows 10, snprintf
tidak lagi identik _snprintf
dengan . Perilaku sekarang snprintf
sesuai standar C99. Perbedaannya adalah bahwa jika Anda kehabisan buffer, snprintf
null-mengakhiri akhir buffer dan mengembalikan jumlah karakter yang akan diperlukan sedangkan _snprintf
tidak menghentikan buffer null dan mengembalikan -1. Selain itu, snprintf()
sertakan satu karakter lagi dalam output karena tidak menghentikan buffer null.
snprintf
_snprintf
dan keluarga format fungsi dan menyimpancount
atau lebih sedikit karakter dalambuffer
.snprintf
selalu menyimpan karakter yang mengakhiriNULL
, memotong output jika perlu.- Jika
snprintf
mengembalikan nilai >count
- 1, output telah dipotong. - Keluarga
_snprintf
fungsi hanya menambahkan karakter yang mengakhiriNULL
jika panjang string yang diformat benar-benar kurang daricount
karakter. - Masing-masing
argument
(jika ada) dikonversi dan merupakan output sesuai dengan spesifikasi format yang sesuai diformat
. Format terdiri dari karakter biasa dan memiliki bentuk dan fungsi yang sama denganformat
argumen untukprintf
. Jika penyalinan terjadi di antara string yang tumpang tindih, perilaku tidak terdefinisi.
Ringkasan perilaku
Untuk tabel berikut:
- Biarkan
sizeOfBuffer
seukuranbuffer
. Jika fungsi mengambilchar
buffer, ukurannya dalam byte. Jika fungsi mengambilwchar_t
buffer, ukuran menentukan jumlah kata 16-bit. - Biarkan
len
menjadi ukuran data yang diformat. Jika fungsi mengambilchar
buffer, ukurannya dalam byte. Jika fungsi mengambilwchar_t
buffer, ukuran menentukan jumlah kata 16-bit. - Karakter merujuk ke
char
karakter untuk fungsi yang mengambilchar
buffer, dan kewchar_t
karakter untuk fungsi yang mengambilwchar_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 |
---|---|---|---|---|
Berhasil | Menulis karakter ke dalam buffer menggunakan string format yang ditentukan. | Jumlah karakter yang ditulis. | T/A | No |
Kesalahan pengodean selama pemformatan | Jika pemrosesan penentu s string , , S atau Z , pemrosesan spesifikasi format berhenti, NULL ditempatkan di awal buffer. |
-1 | EILSEQ (42) |
No |
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) |
No |
buffer == NULL dan count != 0 |
Jika eksekusi berlanjut setelah handler parameter tidak valid dijalankan, set errno dan mengembalikan nilai negatif. |
-1 | EINVAL (22) |
Ya |
count == 0 |
Jumlah karakter yang akan ditulis, tidak termasuk penghentian NULL . Anda dapat menggunakan hasil ini untuk mengalokasikan ruang buffer yang memadai untuk string dan penghentian NULL , lalu memanggil fungsi lagi untuk mengisi buffer. |
T/A | No | |
count < 0 |
Tidak aman: nilai diperlakukan sebagai tidak ditandatangani, kemungkinan menciptakan nilai besar yang menghasilkan penimpaan memori yang mengikuti buffer. | Jumlah karakter yang ditulis | T/A | No |
count < sizeOfBuffer dan len <= count |
Semua data ditulis dan penghentian NULL ditambahkan. |
Jumlah karakter yang ditulis, tidak termasuk yang mengakhiri NULL . |
T/A | No |
count < sizeOfBuffer dan len > count |
Karakter pertama count-1 ditulis diikuti oleh null-terminator. |
Jumlah karakter yang akan ditulis telah count cocok dengan jumlah karakter yang dihasilkan, tidak termasuk null-terminator. |
T/A | No |
count >= sizeOfBuffer dan len < sizeOfBuffer |
Semua data ditulis dengan penghentian NULL . |
Jumlah karakter yang ditulis, tidak termasuk yang mengakhiri NULL . |
T/A | No |
count >= sizeOfBuffer dan len >= sizeOfBuffer |
Tidak aman: Menimpa memori yang mengikuti buffer. | Jumlah karakter yang ditulis, tidak termasuk yang mengakhiri NULL . |
T/A | No |
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. _snprintf
Karena fungsi tidak menjamin penghentian null—khususnya, ketika nilai pengembalian —count
pastikan bahwa fungsi tersebut diikuti oleh kode yang menambahkan terminator null. Untuk informasi selengkapnya, lihat Menghindari overruns buffer.
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
adalah versi _snprintf
karakter lebar ; argumen penunjuk untuk _snwprintf
adalah string karakter lebar. Deteksi kesalahan pengodean mungkin _snwprintf
berbeda dari deteksi di _snprintf
. _snwprintf
, sama seperti swprintf
, menulis output ke string alih-alih tujuan jenis FILE
.
Versi fungsi-fungsi ini yang memiliki _l
akhiran identik kecuali mereka menggunakan parameter lokal yang diteruskan alih-alih lokal utas saat ini.
Di C++, fungsi-fungsi ini memiliki kelebihan beban templat yang memanggil mitra yang lebih baru dan lebih 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 |
_snprintf |
_snprintf |
_snwprintf |
_sntprintf_l |
_snprintf_l |
_snprintf_l |
_snwprintf_l |
Persyaratan
Rutin | Header yang diperlukan |
---|---|
snprintf , , _snprintf _snprintf_l |
<stdio.h> |
_snwprintf , _snwprintf_l |
<stdio.h> atau <wchar.h> |
Untuk informasi kompatibilitas selengkapnya, lihat Kompatibilitas.
Contoh
// 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
Lihat 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