vsnprintf
, _vsnprintf
, _vsnprintf_l
, _vsnwprintf
_vsnwprintf_l
Scrivere l'output formattato mediante un puntatore a un elenco di argomenti. Sono disponibili versioni più sicure di queste funzioni; vedere vsnprintf_s
, _vsnprintf_s
, _vsnprintf_s_l
_vsnwprintf_s
, , . _vsnwprintf_s_l
Sintassi
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
Parametri
buffer
Percorso di archiviazione per l'output.
count
Numero massimo di caratteri da scrivere. Per le funzioni che accettano wchar_t
, è il numero di caratteri wide da scrivere.
format
Specifica di formato.
argptr
Puntatore a un elenco di argomenti.
locale
Impostazioni locali da usare.
Per altre informazioni, vedere Sintassi delle specifiche di formato.
Valore restituito
Numero di caratteri scritti, senza includere l'terminazione NULL
o un valore negativo se si verifica un errore di output.
Per informazioni dettagliate, vedere Riepilogo del comportamento .
Osservazioni:
Ognuna di queste funzioni accetta un puntatore a un elenco di argomenti, quindi formatta i dati e scrive fino a count
caratteri nella memoria a cui punta buffer
. La funzione vsnprintf
scrive sempre un carattere di terminazione Null, anche se tronca l'output. Quando si usa _vsnprintf
e _vsnwprintf
, il buffer viene terminato con null solo se alla fine è presente spazio, ovvero se il numero di caratteri da scrivere è minore di count
.
A partire da UCRT in Visual Studio 2015 e Windows 10, vsnprintf
non è più identico a _vsnprintf
. La vsnprintf
funzione è conforme allo standard C99. _vsnprintf
Viene mantenuta per garantire la compatibilità con le versioni precedenti con il codice precedente. La differenza è che se si esaurisce il buffer, vsnprintf
null termina la fine del buffer e restituisce il numero di caratteri necessari, mentre _vsnprintf
non termina il buffer e restituisce -1. _vsnprintf()
Include anche un altro carattere nell'output perché non termina il buffer.
Importante
Per evitare determinati tipi di rischi per la sicurezza, assicurarsi che format
non sia una stringa definita dall'utente. Per altre informazioni, vedere Evitare sovraccarichi del buffer.
A partire da Windows 10 versione 2004 (build 19041), la printf
famiglia di funzioni stampa numeri a virgola mobile esattamente rappresentabili in base alle regole IEEE 754 per l'arrotondamento. Nelle versioni precedenti di Windows, i numeri a virgola mobile che terminano in '5' verrebbero sempre arrotondati. IEEE 754 indica che devono essere arrotondati alla cifra pari più vicina (nota anche come "Arrotondamento del banchiere"). Ad esempio, sia printf("%1.0f", 1.5)
che printf("%1.0f", 2.5)
devono essere arrotondati a 2. In precedenza, 1,5 arrotonderebbe a 2 e 2,5 arrotonderebbe a 3. Questa modifica influisce solo sui numeri rappresentabili esattamente. Ad esempio, 2.35 (che, se rappresentato in memoria, è più vicino a 2,350000000000000008) continua a arrotondare fino a 2,4. L'arrotondamento eseguito da queste funzioni ora rispetta anche la modalità di arrotondamento a virgola mobile impostata da fesetround
. In precedenza, l'arrotondamento ha sempre scelto FE_TONEAREST
il comportamento. Questa modifica interessa solo i programmi compilati con Visual Studio 2019 versione 16.2 e successive. Per usare il comportamento di arrotondamento a virgola mobile legacy, collegarsi a "legacy_stdio_float_rounding.obj".
Nota
Per assicurarsi che sia disponibile spazio per l'interruzione null quando si chiama _vsnprintf
, _vsnwprintf
_vsnprintf_l
e _vsnwprintf_l
, assicurarsi che count
sia rigorosamente minore della lunghezza del buffer e inizializzare il buffer su Null prima di chiamare la funzione.
Poiché vsnprintf
scrive sempre un valore Null di terminazione, il count
parametro può essere uguale alle dimensioni del buffer.
Le versioni di queste funzioni con il suffisso _l
sono identiche ad eccezione per il fatto che utilizzano il parametro delle impostazioni locali passato al posto di quelle del thread corrente.
In C++ queste funzioni presentano overload di modello che richiamano le relative controparti più recenti e sicure. Per altre informazioni, vedere Proteggere gli overload dei modelli.
Riepilogo del comportamento
Per la tabella seguente:
- Si supponga di
sizeOfBuffer
essere la dimensione dibuffer
. Se la funzione accetta unchar
buffer, le dimensioni sono in byte. Se la funzione accetta unwchar_t
buffer, la dimensione specifica il numero di parole a 16 bit. - Si supponga di
len
essere la dimensione dei dati formattati. Se la funzione accetta unchar
buffer, le dimensioni sono in byte. Se la funzione accetta unwchar_t
buffer, la dimensione specifica il numero di parole a 16 bit. - I caratteri fanno riferimento ai
char
caratteri per le funzioni che accettano unchar
buffer e aiwchar_t
caratteri per le funzioni che accettano unwchar_t
buffer. - Per altre informazioni sul gestore di parametri non validi, vedere Convalida dei parametri.
Condizione | Comportamento | Valore restituito | errno |
Richiama il gestore di parametri non validi |
---|---|---|---|---|
Success | Scrive i caratteri nel buffer usando la stringa di formato specificata. | Numero di caratteri scritti, senza contare il carattere Null di terminazione. | N/D | No |
Errore di codifica durante la formattazione | Se l'elaborazione dell'identificatore s di stringa , S o Z , viene arrestata l'elaborazione della specifica del formato. |
-1 | EILSEQ (42) |
No |
Errore di codifica durante la formattazione | Se l'identificatore c di carattere di elaborazione o C , il carattere non valido viene ignorato. Il numero di caratteri scritti non viene incrementato per il carattere ignorato, né per i dati scritti. L'elaborazione della specifica del formato continua dopo aver ignorato l'identificatore con l'errore di codifica. |
Numero di caratteri scritti, senza includere l'oggetto di terminazione NULL . |
EILSEQ (42) |
No |
buffer == NULL e count != 0 |
Se l'esecuzione continua dopo l'esecuzione del gestore di parametri non validi, imposta errno e restituisce un valore negativo. |
-1 | EINVAL (22) |
Sì |
count == 0 |
Nessun dato scritto | Numero di caratteri che sarebbero stati scritti, senza includere l'oggetto di terminazione NULL . È possibile usare questo risultato per allocare spazio del buffer sufficiente per la stringa e una terminazione NULL e quindi chiamare di nuovo la funzione per riempire il buffer. |
N/D | No |
count < 0 |
Unsafe: il valore viene considerato senza segno, creando probabilmente un valore di grandi dimensioni che comporta la sovrascrittura della memoria che segue il buffer. | Numero di caratteri scritti. | N/D | No |
count < sizeOfBuffer e len <= count |
Tutti i dati vengono scritti e viene aggiunta una terminazione NULL . |
Numero di caratteri scritti, senza includere l'oggetto di terminazione NULL . |
N/D | No |
count < sizeOfBuffer e len > count |
I primi count-1 caratteri vengono scritti seguiti da un carattere di terminazione Null. |
Il numero di caratteri che sarebbero stati scritti corrispondeva count al numero di caratteri da restituire, senza includere il carattere di terminazione Null. |
N/D | No |
count >= sizeOfBuffer e len < sizeOfBuffer |
Tutti i dati vengono scritti con un carattere di terminazione NULL . |
Numero di caratteri scritti, senza includere l'oggetto di terminazione NULL . |
N/D | No |
count >= sizeOfBuffer e len >= sizeOfBuffer |
Unsafe: sovrascrive la memoria che segue il buffer. | Numero di caratteri scritti, senza includere l'oggetto di terminazione NULL . |
N/D | No |
format == NULL |
Non viene scritto alcun dato. Se l'esecuzione continua dopo l'esecuzione del gestore di parametri non validi, imposta errno e restituisce un valore negativo. |
-1 | EINVAL (22) |
Sì |
Per informazioni su questi e altri codici di errore, vedere _doserrno
, errno
, _sys_errlist
e _sys_nerr
.
Mapping di routine di testo generico
TCHAR.H routine |
_UNICODE e _MBCS non definito |
_MBCS definito |
_UNICODE definito |
---|---|---|---|
_vsntprintf |
_vsnprintf |
_vsnprintf |
_vsnwprintf |
_vsntprintf_l |
_vsnprintf_l |
_vsnprintf_l |
_vsnwprintf_l |
Requisiti
Ciclo | Intestazione obbligatoria (C) | Intestazione obbligatoria (C++) |
---|---|---|
vsnprintf , _vsnprintf , _vsnprintf_l |
<stdio.h> |
<stdio.h> oppure <cstdio> |
_vsnwprintf , _vsnwprintf_l |
<stdio.h> oppure <wchar.h> |
<stdio.h> , <wchar.h> , <cstdio> o <cwchar> |
Le _vsnprintf
funzioni , _vsnwprintf
_vsnprintf_l
e _vsnwprintf_l
sono specifiche di Microsoft. Per altre informazioni sulla compatibilità, vedere Compatibility (Compatibilità).
Esempio: Usare caratteri wide con _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!
Il comportamento cambia se si usa vsnprintf, insieme ai parametri con stringa "narrow". Il parametro count
può corrispondere alle dimensioni intere del buffer e il valore restituito è il numero di caratteri che verrebbero scritti se count
fosse abbastanza grande:
Esempio: usare vsnprintf()
con stringhe strette
// 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!
Vedi anche
I/O di flusso
Funzioni vprintf
Sintassi della specifica del formato: printf
e wprintf
funzioni
fprintf
, _fprintf_l
, fwprintf
_fwprintf_l
printf
, _printf_l
, wprintf
_wprintf_l
sprintf
, _sprintf_l
, swprintf
, _swprintf_l
__swprintf_l
va_arg
, va_copy
, va_end
va_start