vsnprintf
, , _vsnprintf_l
, , _vsnprintf
_vsnwprintf
_vsnwprintf_l
Grave saída formatada usando um ponteiro para uma lista de argumentos. Estão disponíveis versões mais seguras dessas funções; confira vsnprintf_s
, _vsnprintf_s
, _vsnprintf_s_l
, _vsnwprintf_s
, _vsnwprintf_s_l
.
Sintaxe
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
Parâmetros
buffer
Local de armazenamento de saída.
count
O número máximo de caracteres a serem gravados. Para as funções que tomam wchar_t
, é o número de caracteres largos para escrever.
format
Especificação de formato.
argptr
Ponteiro para a lista de argumentos.
locale
A localidade a ser usada.
Para obter mais informações, consulte Sintaxe de especificação de formato.
Valor retornado
O número de caracteres gravados, não incluindo o encerramento NULL
, ou um valor negativo se ocorrer um erro de saída.
Consulte Resumo do comportamento para obter detalhes.
Comentários
Cada uma dessas funções usa um ponteiro para uma lista de argumentos, em seguida, formata os dados e grava até count
caracteres na memória apontada por buffer
. A função vsnprintf
sempre grava um terminador nulo, mesmo que ele trunque a saída. Quando você usa _vsnprintf
e _vsnwprintf
, o buffer é terminado em nulo somente se houver espaço no final (ou seja, se o número de caracteres a serem gravados for menor que count
).
Começando com o UCRT no Visual Studio 2015 e Windows 10, vsnprintf
não é mais idêntico a _vsnprintf
. A vsnprintf
função está em conformidade com o padrão C99, _vsnprintf
é mantida para compatibilidade com versões anteriores com código mais antigo. A diferença é que, se você ficar sem buffer, null-termina o final do buffer e retorna o número de caracteres que teriam sido necessários, vsnprintf
enquanto _vsnprintf
não termina null-termina o buffer e retorna -1. Além disso, _vsnprintf()
inclui mais um caractere na saída porque ele não termina nulo o buffer.
Importante
Para evitar certos tipos de riscos de segurança, verifique se não format
é uma cadeia de caracteres definida pelo usuário. Para obter mais informações, consulte Evitando saturações de buffer.
Começando pelo Windows 10 versão 2004 (build 19041), a família de funções printf
imprime números de ponto flutuante exatamente representáveis de acordo com as regras do IEEE 754 para arredondamento. Em versões anteriores do Windows, números de ponto flutuante que pudessem ser representados com exatidão e que terminassem em '5' eram sempre arredondados para cima. O IEEE 754 afirma que eles precisam arredondar para o dígito par mais próximo (também conhecido como "arredondamento bancário"). Por exemplo, ambos printf("%1.0f", 1.5)
e printf("%1.0f", 2.5)
devem ser arredondados para 2. Anteriormente, 1,5 seria arredondado para 2 e 2,5 para 3. Essa alteração afeta apenas números que possam ser representados com exatidão. Por exemplo, 2,35 (que, quando representado na memória, está mais próximo de 2,35000000000000008) continua arredondando para 2,4. O arredondamento feito por essas funções agora também respeita o modo de arredondamento de ponto flutuante definido por fesetround
. Anteriormente, o arredondamento sempre escolhia o comportamento FE_TONEAREST
. Essa alteração afeta apenas os programas criados usando o Visual Studio 2019 versão 16.2 e posteriores. Para usar o comportamento de arredondamento de ponto flutuante herdado, vincule-o a 'legacy_stdio_float_rounding.obj'.
Observação
Para garantir que haja espaço para o nulo de terminação ao chamar _vsnprintf
, _vsnprintf_l
, _vsnwprintf
e _vsnwprintf_l
, certifique-se de que count
seja estritamente menor do que o comprimento do buffer e inicialize o buffer como nulo antes de chamar a função.
Como vsnprintf
sempre grava um null de terminação, o count
parâmetro pode ser igual ao tamanho do buffer.
As versões dessas funções com o sufixo _l
são idênticas, com a exceção de usarem o parâmetro de localidade passado, em vez da localidade do thread atual.
No C++, essas funções têm sobrecargas de modelo que invocam os equivalentes mais novos e seguros dessas funções. Para obter mais informações, consulte Sobrecargas de modelo seguras.
Resumo do comportamento
Para a tabela a seguir:
- Que
sizeOfBuffer
seja do tamanho debuffer
. Se a função usa umchar
buffer, o tamanho é em bytes. Se a função usar umwchar_t
buffer, o tamanho especificará o número de palavras de 16 bits. - Seja
len
o tamanho dos dados formatados. Se a função usa umchar
buffer, o tamanho é em bytes. Se a função usar umwchar_t
buffer, o tamanho especificará o número de palavras de 16 bits. - Caracteres referem-se a caracteres para funções que usam um buffer e a
char
wchar_t
caracteres para funções que usam umchar
wchar_t
buffer. - Para obter mais informações sobre o manipulador de parâmetros inválidos, consulte Validação de parâmetro.
Condição | Comportamental | Valor retornado | errno |
Invoca um manipulador de parâmetro inválido |
---|---|---|---|---|
Êxito | Grava os caracteres no buffer usando a cadeia de caracteres de formato especificada. | O número de caracteres escritos, sem contar o caractere nulo de encerramento. | N/D | Não |
Erro de codificação durante a formatação | Se o processamento do especificador s de cadeia de caracteres , ou Z , S o processamento de especificação de formato for interrompido. |
-1 | EILSEQ (42) |
Não |
Erro de codificação durante a formatação | Se o especificador c de caracteres de processamento ou C , o caractere inválido será ignorado. O número de caracteres gravados não é incrementado para o caractere ignorado, nem os dados são gravados para ele. O processamento da especificação de formato continua depois de ignorar o especificador com o erro de codificação. |
O número de caracteres escritos, não incluindo o término NULL . |
EILSEQ (42) |
Não |
buffer == NULL e count != 0 |
Se a execução continuar após a execução do manipulador de parâmetros inválido, definirá errno e retornará um valor negativo. |
-1 | EINVAL (22) |
Sim |
count == 0 |
Nenhum dado é gravado | O número de caracteres que teriam sido escritos, não incluindo o encerramento NULL . Você pode usar esse resultado para alocar espaço de buffer suficiente para a cadeia de caracteres e um encerramento NULL e, em seguida, chamar a função novamente para preencher o buffer. |
N/D | Não |
count < 0 |
Não seguro: o valor é tratado como não assinado, provavelmente criando um valor grande que resulta na substituição da memória que segue o buffer. | O número de caracteres gravados. | N/D | Não |
count < sizeOfBuffer e len <= count |
Todos os dados são gravados e uma rescisão NULL é anexada. |
O número de caracteres escritos, não incluindo o término NULL . |
N/D | Não |
count < sizeOfBuffer e len > count |
Os primeiros count-1 caracteres são escritos seguidos por um terminador nulo. |
O número de caracteres que teriam sido gravados correspondeu count ao número de caracteres a serem produzidos, não incluindo o terminador nulo. |
N/D | Não |
count >= sizeOfBuffer e len < sizeOfBuffer |
Todos os dados são gravados com um arquivo NULL . |
O número de caracteres escritos, não incluindo o término NULL . |
N/D | Não |
count >= sizeOfBuffer e len >= sizeOfBuffer |
Não seguro: substitui a memória que segue o buffer. | O número de caracteres escritos, não incluindo o término NULL . |
N/D | Não |
format == NULL |
Nenhum dado é gravado. Se a execução continuar após a execução do manipulador de parâmetros inválido, definirá errno e retornará um valor negativo. |
-1 | EINVAL (22) |
Sim |
Para obter informações sobre esses e outros códigos de erro, confira _doserrno
, errno
, _sys_errlist
e _sys_nerr
.
Mapeamentos de rotina de texto genérico
Rotina TCHAR.H |
_UNICODE e _MBCS não definidos |
_MBCS definido |
_UNICODE definido |
---|---|---|---|
_vsntprintf |
_vsnprintf |
_vsnprintf |
_vsnwprintf |
_vsntprintf_l |
_vsnprintf_l |
_vsnprintf_l |
_vsnwprintf_l |
Requisitos
Rotina | Cabeçalho necessário (C) | Cabeçalho necessário (C++) |
---|---|---|
vsnprintf , _vsnprintf , _vsnprintf_l |
<stdio.h> |
<stdio.h> ou <cstdio> |
_vsnwprintf , _vsnwprintf_l |
<stdio.h> ou <wchar.h> |
<stdio.h> , <wchar.h> , <cstdio> ou <cwchar> |
As funções _vsnprintf
, _vsnprintf_l
, _vsnwprintf
e _vsnwprintf_l
são específicas da Microsoft. Para obter informações sobre compatibilidade, consulte Compatibilidade.
Exemplo: usar caracteres largos com _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!
O comportamento será alterado se você usar vsnprintf em vez disso, juntamente com parâmetros de cadeia estreita. O parâmetro count
pode ser o tamanho inteiro do buffer e o valor retornado é o número de caracteres que teriam sido gravados se count
fosse grande o suficiente:
Exemplo: usar vsnprintf()
com cadeias de caracteres estreitas
// 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!
Confira também
E/S de fluxo
Funções vprintf
Sintaxe de especificação de formato: printf
e wprintf
funções
fprintf
, , , _fprintf_l
fwprintf
_fwprintf_l
printf
, , , _printf_l
wprintf
_wprintf_l
sprintf
, , swprintf
, , _sprintf_l
_swprintf_l
__swprintf_l
va_arg
, , , va_copy
va_end
va_start
Comentários
https://aka.ms/ContentUserFeedback.
Em breve: Ao longo de 2024, eliminaremos os problemas do GitHub como o mecanismo de comentários para conteúdo e o substituiremos por um novo sistema de comentários. Para obter mais informações, consulteEnviar e exibir comentários de