Dela via


vsnprintf, _vsnprintf, _vsnprintf_l, , , _vsnwprintf_vsnwprintf_l

Skriv formaterade utdata med en pekare till en lista med argument. Säkrare versioner av dessa funktioner finns tillgängliga; Se vsnprintf_s, _vsnprintf_s, _vsnprintf_s_l, _vsnwprintf_s, . _vsnwprintf_s_l

Syntax

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

Parameterar

buffer
Lagringsplats för utdata.

count
Maximalt antal tecken att skriva. För de funktioner som tar wchar_tär det antalet breda tecken som ska skrivas.

format
Specifikation av format.

argptr
Pekare till en lista med argument.

locale
Språkvarianten som ska användas.

Mer information finns i Syntax för formatspecifikation.

Returvärde

Antalet skrivna tecken, exklusive avslutande NULL, eller ett negativt värde om ett utdatafel inträffar.

Mer information finns i Beteendesammanfattning .

Anmärkningar

Var och en av dessa funktioner tar en pekare till en argumentlista, formaterar sedan data och skriver upp till count tecken till minnet som pekas på av buffer. Funktionen vsnprintf skriver alltid en null-terminator, även om den trunkerar utdata. När du använder _vsnprintf and _vsnwprintfavslutas bufferten null endast om det finns utrymme i slutet (d.v.s. om antalet tecken som ska skrivas är mindre än count).

Från och med UCRT i Visual Studio 2015 och Windows 10 vsnprintf är det inte längre identiskt _vsnprintfmed . Funktionen vsnprintf överensstämmer med C99-standarden _vsnprintf och behålls för bakåtkompatibilitet med äldre kod. Skillnaden är att om du får slut på buffert vsnprintf avslutar null slutet av bufferten och returnerar det antal tecken som skulle ha krävts, medan _vsnprintf bufferten inte null-avslutas och returnerar -1. _vsnprintf() Innehåller också ytterligare ett tecken i utdata eftersom det inte null-avslutar bufferten.

Viktigt!

För att förhindra vissa typer av säkerhetsrisker bör du se till att det format inte är en användardefinierad sträng. Mer information finns i Undvika buffertöverskridningar. Från och med Windows 10 version 2004 (version 19041) skriver funktionsfamiljen printf ut exakt representerande flyttalsnummer enligt IEEE 754-reglerna för avrundning. I tidigare versioner av Windows skulle exakt representerande flyttalsnummer som slutar på "5" alltid avrunda uppåt. IEEE 754 anger att de måste avrunda till den närmaste jämna siffran (även kallat "Bankers avrundning"). Till exempel bör både printf("%1.0f", 1.5) och printf("%1.0f", 2.5) avrunda till 2. Tidigare skulle 1,5 avrunda till 2 och 2,5 skulle avrunda till 3. Den här ändringen påverkar endast exakt representerande tal. Till exempel fortsätter 2.35 (som, när det representeras i minnet, är närmare 2.3500000000000000008) att avrunda upp till 2,4. Avrundning som utförs av dessa funktioner respekterar nu också flyttalsrundningsläget som anges av fesetround. Tidigare valde FE_TONEAREST avrundning alltid beteende. Den här ändringen påverkar endast program som skapats med Visual Studio 2019 version 16.2 och senare. Om du vill använda det äldre avrundningsbeteendet för flyttalser länkar du till legacy_stdio_float_rounding.obj.

Anmärkning

För att säkerställa att det finns utrymme för det avslutande null-värdet när du anropar _vsnprintf, _vsnprintf_l_vsnwprintf, och _vsnwprintf_l, måste du se till att det count är strikt mindre än buffertlängden och initiera bufferten till null innan du anropar funktionen.

Eftersom vsnprintf alltid skriver ett avslutande null-värde count kan parametern vara lika med storleken på bufferten.

Versionerna av dessa funktioner med suffixet _l är identiska, förutom att de använder parametern locale som skickas i stället för den aktuella trådspråkinställningen.

I C++ har dessa funktioner mallöverlagringar som anropar de nyare, säkra motsvarigheterna till dessa funktioner. För mer information, se Secure template overloads.

Beteendesammanfattning

För följande tabell:

  • Låt vara sizeOfBuffer storleken på buffer. Om funktionen tar en char buffert är storleken i byte. Om funktionen tar en wchar_t buffert anger storleken antalet 16-bitars ord.
  • Låt vara len storleken på de formaterade data. Om funktionen tar en char buffert är storleken i byte. Om funktionen tar en wchar_t buffert anger storleken antalet 16-bitars ord.
  • Tecken refererar till char tecken för funktioner som tar en char buffert och till wchar_t tecken för funktioner som tar en wchar_t buffert.
  • Mer information om den ogiltiga parameterhanteraren finns i Parameterverifiering.
Tillstånd Beteende Returvärde errno Anropar ogiltig parameterhanterare
Framgång Skriver tecknen till bufferten med den angivna formatsträngen. Antalet skrivna tecken, exklusive det avslutande null-tecknet. Inte tillgänglig Nej
Kodningsfel under formatering Om du bearbetar strängspecificeraren s, S, eller Z, stoppas bearbetningen av formatspecifikationen. -1 EILSEQ (42) Nej
Kodningsfel under formatering Om bearbetningsteckenspecificeraren c eller C, hoppas det ogiltiga tecknet över. Antalet tecken som skrivs ökas inte för det överhoppade tecknet och inga data skrivs för det. Bearbetningen av formatspecifikationen fortsätter när du har hoppat över specificeraren med kodningsfelet. Antalet tecken som skrivs, inklusive avslutande NULL. EILSEQ (42) Nej
buffer == NULL och count != 0 Om körningen fortsätter efter att den ogiltiga parameterhanteraren har körts anger errno och returnerar ett negativt värde. -1 EINVAL (22) Ja
buffer == NULL och count == 0 Inga data skrivs Antalet tecken som skulle ha skrivits, inklusive avslutande NULL. Du kan använda det här resultatet för att allokera tillräckligt med buffertutrymme för strängen och en avslutande NULL, och sedan anropa funktionen igen för att fylla bufferten. Inte tillgänglig Nej
count == 0 Inga data skrivs -1 ERANGE (34) Nej
count < 0 Osäkert: värdet behandlas som osignerat, vilket sannolikt skapar ett stort värde som resulterar i att minnet som följer bufferten skrivs över. Antalet tecken som skrivits. Inte tillgänglig Nej
count < sizeOfBuffer och len <= count Alla data skrivs och en avslutande NULL läggs till. Antalet tecken som skrivs, inklusive avslutande NULL. Inte tillgänglig Nej
count < sizeOfBuffer och len > count De första count-1 tecknen skrivs följt av en null-terminator. Antalet tecken som skulle ha skrivits hade count matchat antalet tecken som ska matas ut, inklusive null-terminatorn. Inte tillgänglig Nej
count >= sizeOfBuffer och len < sizeOfBuffer Alla data skrivs med en avslutande NULL. Antalet tecken som skrivs, inklusive avslutande NULL. Inte tillgänglig Nej
count >= sizeOfBuffer och len >= sizeOfBuffer Osäker: skriver över minnet som följer bufferten. Antalet tecken som skrivs, inklusive avslutande NULL. Inte tillgänglig Nej
format == NULL Inga data skrivs. Om körningen fortsätter efter att den ogiltiga parameterhanteraren har körts anger errno och returnerar ett negativt värde. -1 EINVAL (22) Ja

Information om dessa och andra felkoder finns i _doserrno, errno, _sys_errlistoch _sys_nerr.

Allmän textrutinmappning

TCHAR.H rutin _UNICODE och _MBCS inte definierat _MBCS definierad _UNICODE definierad
_vsntprintf _vsnprintf _vsnprintf _vsnwprintf
_vsntprintf_l _vsnprintf_l _vsnprintf_l _vsnwprintf_l

Kravspecifikation

Rutin Obligatoriskt sidhuvud (C) Obligatoriskt huvud (C++)
vsnprintf, , _vsnprintf_vsnprintf_l <stdio.h> <stdio.h> eller <cstdio>
_vsnwprintf, _vsnwprintf_l <stdio.h> eller <wchar.h> <stdio.h>, <wchar.h>, <cstdio>eller <cwchar>

Funktionerna _vsnprintf, _vsnprintf_l, _vsnwprintf och _vsnwprintf_l är Microsoft-specifika. Mer kompatibilitetsinformation finns i Kompatibilitet.

Exempel: Använd breda tecken med _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!

Beteendet ändras om du använder vsnprintf i stället, tillsammans med smala strängparametrar. Parametern count kan vara hela storleken på bufferten och returvärdet är det antal tecken som skulle ha skrivits om count det var tillräckligt stort:

Exempel: Använd vsnprintf() med smala strängar

// 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!

Se även

Stream I/O-
vprintf funktioner
Syntax för formatspecifikation: printf och wprintf funktioner
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