Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
Tulis output berformat menggunakan penunjuk ke daftar argumen. Versi yang lebih aman dari fungsi-fungsi ini tersedia; lihat vsnprintf_s, _vsnprintf_s, , _vsnprintf_s_l, _vsnwprintf_s_vsnwprintf_s_l.
Sintaksis
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
Parameter-parameternya
buffer
Lokasi penyimpanan untuk output.
count
Jumlah karakter maksimum yang akan ditulis. Untuk fungsi yang mengambil wchar_t, itu adalah jumlah karakter lebar yang akan ditulis.
format
Spesifikasi format.
argptr
Penunjuk ke daftar argumen.
locale
Lokal yang akan digunakan.
Untuk informasi selengkapnya, lihat Sintaks spesifikasi format.
Mengembalikan nilai
Jumlah karakter yang ditulis, tidak termasuk pengakhiran NULL, atau nilai negatif jika terjadi kesalahan output.
Lihat Ringkasan perilaku untuk detailnya.
Komentar
Masing-masing fungsi ini mengambil penunjuk ke daftar argumen, lalu memformat data, dan menulis count karakter ke memori yang ditunjuk oleh buffer. Fungsi selalu vsnprintf menulis terminator null, bahkan jika memotong output. Saat Anda menggunakan _vsnprintf dan _vsnwprintf, buffer dihentikan secara null hanya jika ada ruang di akhir (yaitu, jika jumlah karakter yang akan ditulis kurang dari count).
Dimulai dengan UCRT di Visual Studio 2015 dan Windows 10, vsnprintf tidak lagi identik _vsnprintfdengan . Fungsi ini vsnprintf sesuai dengan standar C99; _vsnprintf disimpan untuk kompatibilitas mundur dengan kode yang lebih lama. Perbedaannya adalah bahwa jika Anda kehabisan buffer, vsnprintf null-terminasi akhir buffer dan mengembalikan jumlah karakter yang diperlukan, sementara _vsnprintf tidak null-terminate buffer dan mengembalikan -1. Selain itu, _vsnprintf() sertakan satu karakter lagi dalam output karena tidak menghentikan buffer null.
Penting
Untuk mencegah jenis risiko keamanan tertentu, pastikan itu format bukan string yang ditentukan pengguna. 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.
Nota
Untuk memastikan bahwa ada ruang untuk null pengakhiran saat memanggil _vsnprintf, _vsnprintf_l, _vsnwprintf dan _vsnwprintf_l, pastikan itu count benar-benar kurang dari panjang buffer dan inisialisasi buffer ke null sebelum memanggil fungsi.
Karena vsnprintf selalu menulis null pengakhiran, count parameter mungkin sama dengan ukuran buffer.
Versi fungsi ini dengan _l akhiran identik kecuali bahwa mereka menggunakan parameter lokal yang diteruskan alih-alih lokal utas saat ini.
Di C++, fungsi-fungsi ini memiliki kelebihan templat yang memanggil rekan yang lebih baru dan aman dari fungsi-fungsi ini. Untuk informasi selengkapnya, lihat Mengamankan kelebihan beban templat.
Ringkasan perilaku
Untuk tabel berikut:
- Biarkan
sizeOfBufferseukuranbuffer. Jika fungsi mengambilcharbuffer, ukurannya dalam byte. Jika fungsi mengambilwchar_tbuffer, ukuran menentukan jumlah kata 16-bit. - Biarkan
lenmenjadi ukuran data yang diformat. Jika fungsi mengambilcharbuffer, ukurannya dalam byte. Jika fungsi mengambilwchar_tbuffer, ukuran menentukan jumlah kata 16-bit. - Karakter merujuk ke
charkarakter untuk fungsi yang mengambilcharbuffer, dan kewchar_tkarakter untuk fungsi yang mengambilwchar_tbuffer. - Untuk informasi selengkapnya tentang handler parameter yang tidak valid, lihat Validasi Parameter.
| Keadaan | Perilaku | Mengembalikan nilai | errno |
Memanggil handler parameter yang tidak valid |
|---|---|---|---|---|
| Keberhasilan | Menulis karakter ke dalam buffer menggunakan string format yang ditentukan. | Jumlah karakter yang ditulis, tidak termasuk karakter null yang mengakhiri. | Tidak tersedia | Tidak. |
| Kesalahan pengodean selama pemformatan | Jika pemrosesan penentu sstring , S, atau 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 == NULL dan count != 0 |
Jika eksekusi berlanjut setelah handler parameter tidak valid dijalankan, set errno dan mengembalikan nilai negatif. |
-1 |
EINVAL (22) |
Ya |
buffer == NULL dan count == 0 |
Tidak ada data yang ditulis | 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. |
Tidak tersedia | Tidak. |
count == 0 |
Tidak ada data yang ditulis | -1 |
ERANGE (34) |
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 tersedia | Tidak. |
count < sizeOfBuffer dan len <= count |
Semua data ditulis dan penghentian NULL ditambahkan. |
Jumlah karakter yang ditulis, tidak termasuk yang mengakhiri NULL. |
Tidak tersedia | Tidak. |
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. |
Tidak tersedia | Tidak. |
count >= sizeOfBuffer dan len < sizeOfBuffer |
Semua data ditulis dengan penghentian NULL. |
Jumlah karakter yang ditulis, tidak termasuk yang mengakhiri NULL. |
Tidak tersedia | Tidak. |
count >= sizeOfBuffer dan len >= sizeOfBuffer |
Tidak aman: menimpa memori yang mengikuti buffer. | Jumlah karakter yang ditulis, tidak termasuk yang mengakhiri NULL. |
Tidak tersedia | 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.
Pemetaan rutin teks generik
TCHAR.H Rutin |
_UNICODE dan _MBCS tidak ditentukan |
_MBCS Didefinisikan |
_UNICODE Didefinisikan |
|---|---|---|---|
_vsntprintf |
_vsnprintf |
_vsnprintf |
_vsnwprintf |
_vsntprintf_l |
_vsnprintf_l |
_vsnprintf_l |
_vsnwprintf_l |
Persyaratan
| Rutin | Header yang diperlukan (C) | Header yang diperlukan (C++) |
|---|---|---|
vsnprintf, , _vsnprintf_vsnprintf_l |
<stdio.h> |
<stdio.h> atau <cstdio> |
_vsnwprintf, _vsnwprintf_l |
<stdio.h> atau <wchar.h> |
<stdio.h>, <wchar.h>, <cstdio>, atau <cwchar> |
_vsnprintfFungsi , _vsnprintf_l, _vsnwprintf dan _vsnwprintf_l bersifat khusus Microsoft. Untuk informasi kompatibilitas selengkapnya, lihat Kompatibilitas.
Contoh: Gunakan karakter lebar dengan _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!
Perilaku berubah jika Anda menggunakan vsnprintf sebagai gantinya, bersama dengan parameter string sempit. Parameter count dapat berupa seluruh ukuran buffer, dan nilai yang dikembalikan adalah jumlah karakter yang akan ditulis jika count cukup besar:
Contoh: Gunakan vsnprintf() dengan string sempit
// 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!
Lihat juga
Streaming I/O
vprintf berfungsi sebagai
Sintaks spesifikasi format: printf dan wprintf fungsi
fprintf, , _fprintf_lfwprintf,_fwprintf_l
printf, , _printf_lwprintf,_wprintf_l
sprintf, _sprintf_l, , swprintf, _swprintf_l__swprintf_l
va_arg, , va_copyva_end,va_start