Condividi tramite


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 NULLo 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_le _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 di buffer. Se la funzione accetta un char buffer, le dimensioni sono in byte. Se la funzione accetta un wchar_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 un char buffer, le dimensioni sono in byte. Se la funzione accetta un wchar_t buffer, la dimensione specifica il numero di parole a 16 bit.
  • I caratteri fanno riferimento ai char caratteri per le funzioni che accettano un char buffer e ai wchar_t caratteri per le funzioni che accettano un wchar_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 sdi stringa , So 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)
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 NULLe 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)

Per informazioni su questi e altri codici di errore, vedere _doserrno, errno, _sys_errliste _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 _vsnprintffunzioni , _vsnwprintf _vsnprintf_le _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_endva_start