Nota
O acesso a esta página requer autorização. Podes tentar iniciar sessão ou mudar de diretório.
O acesso a esta página requer autorização. Podes tentar mudar de diretório.
Escreva a saída formatada usando um ponteiro para uma lista de argumentos. Estão disponíveis versões mais seguras destas funções; ver 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 para saída.
count
Número máximo de caracteres para gravar. Para as funções que levam wchar_t, é o número de caracteres largos para escrever.
format
Especificação do formato.
argptr
Ponteiro para a lista de argumentos.
locale
A localidade a ser usada.
Para obter mais informações, consulte Sintaxe da especificação de formato.
Valor de retorno
O número de caracteres gravados, não incluindo a terminação NULL, ou um valor negativo se ocorrer um erro de saída.
Consulte Resumo do comportamento para obter detalhes.
Observações
Cada uma dessas funções leva um ponteiro para uma lista de argumentos, formata os dados e grava em count caracteres na memória apontada por buffer. A vsnprintf função sempre grava um terminador nulo, mesmo que trunce a saída. Quando você usa _vsnprintf e _vsnwprintf, o buffer é terminado nulo somente se houver espaço no final (ou seja, se o número de caracteres para gravar for menor que count).
A partir do UCRT no Visual Studio 2015 e no Windows 10, vsnprintf não é mais idêntico ao _vsnprintf. A vsnprintf função está em conformidade com o padrão C99, _vsnprintf é mantida para compatibilidade com código mais antigo. A diferença é que, se você ficar sem buffer, vsnprintf null-termina o final do buffer e retorna o número de caracteres que teriam sido necessários, enquanto _vsnprintf não 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, certifique-se de que format não é uma cadeia de caracteres definida pelo usuário. Para obter mais informações, consulte Evitando saturações de buffer.
A partir do Windows 10 versão 2004 (build 19041), a família de funções imprime printf números de ponto flutuante exatamente representáveis de acordo com as regras IEEE 754 para arredondamento. Em versões anteriores do Windows, números de ponto flutuante exatamente representáveis terminando em '5' sempre arredondavam para cima. IEEE 754 afirma que eles devem arredondar para o dígito par mais próximo (também conhecido como "Arredondamento do Banqueiro"). Por exemplo, ambos printf("%1.0f", 1.5) e printf("%1.0f", 2.5) deve arredondar para 2. Anteriormente, 1,5 arredondava para 2 e 2,5 arredondava para 3. Esta alteração afeta apenas números exatamente representáveis. Por exemplo, 2.35 (que, quando representado na memória, está mais próximo de 2.35000000000000008) continua a arredondar para 2.4. O arredondamento feito por essas funções agora também respeita o modo de arredondamento de ponto flutuante definido pela fesetround. Anteriormente, o arredondamento sempre escolhia o FE_TONEAREST comportamento. Essa alteração afeta apenas os programas criados usando o Visual Studio 2019 versão 16.2 e posterior. Para usar o comportamento de arredondamento de ponto flutuante herdado, vincule-se 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_vsnwprintfe _vsnwprintf_l, certifique-se de que é estritamente menor do que count o comprimento do buffer e inicialize o buffer para nulo antes de chamar a função.
Como vsnprintf sempre grava um nulo 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, exceto que elas usam o parâmetro locale passado em vez da localidade thread atual.
Em C++, essas funções têm sobrecargas de modelo que invocam as contrapartes mais recentes e seguras dessas funções. Para obter mais informações, consulte Sobrecargas de modelo seguro.
Resumo do comportamento
Para a tabela a seguir:
- Seja
sizeOfBufferdo tamanho debuffer. Se a função usa umcharbuffer, o tamanho é em bytes. Se a função usa umwchar_tbuffer, o tamanho especifica o número de palavras de 16 bits. - Seja
leno tamanho dos dados formatados. Se a função usa umcharbuffer, o tamanho é em bytes. Se a função usa umwchar_tbuffer, o tamanho especifica o número de palavras de 16 bits. - Caracteres referem-se a
charcaracteres para funções que usam umcharbuffer e awchar_tcaracteres para funções que usam umwchar_tbuffer. - Para obter mais informações sobre o manipulador de parâmetros inválido, consulte Validação de parâmetros.
| Condição | Comportamento | Valor de retorno | errno |
Invoca manipulador de parâmetros inválido |
|---|---|---|---|---|
| Sucesso | Grava os caracteres no buffer usando a cadeia de caracteres de formato especificado. | O número de caracteres escritos, sem contar o caractere nulo de terminação. | N/A | Não |
| Erro de codificação durante a formatação | Se o processamento do especificador sde cadeia de caracteres, S, ou Z, o processamento da especificação de formato for interrompido. |
-1 |
EILSEQ (42) |
Não |
| Erro de codificação durante a formatação | Se processar o especificador c de caracteres ou C, o caractere inválido será ignorado. O número de caracteres escritos não é incrementado para o caractere ignorado, nem são gravados dados 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 gravados, não incluindo a terminação NULL. |
EILSEQ (42) |
Não |
buffer == NULL e count != 0 |
Se a execução continuar depois que o manipulador de parâmetros inválido for executado, definirá errno e retornará um valor negativo. |
-1 |
EINVAL (22) |
Sim |
buffer == NULL e 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 uma terminação NULLe, em seguida, chamar a função novamente para preencher o buffer. |
N/A | Não |
count == 0 |
Nenhum dado é gravado | -1 |
ERANGE (34) |
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 escritos. | N/A | Não |
count < sizeOfBuffer e len <= count |
Todos os dados são gravados e uma terminação NULL é anexada. |
O número de caracteres gravados, não incluindo a terminação NULL. |
N/A | 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 para a saída, não incluindo o terminador nulo. |
N/A | Não |
count >= sizeOfBuffer e len < sizeOfBuffer |
Todos os dados são gravados com uma terminação NULL. |
O número de caracteres gravados, não incluindo a terminação NULL. |
N/A | Não |
count >= sizeOfBuffer e len >= sizeOfBuffer |
Não seguro: substitui a memória que segue o buffer. | O número de caracteres gravados, não incluindo a terminação NULL. |
N/A | Não |
format == NULL |
Nenhum dado é gravado. Se a execução continuar depois que o manipulador de parâmetros inválido for executado, definirá errno e retornará um valor negativo. |
-1 |
EINVAL (22) |
Sim |
Para obter informações sobre esses e outros códigos de erro, consulte _doserrno, errno, _sys_errliste _sys_nerr.
Mapeamentos de rotina de texto genérico
TCHAR.H rotina |
_UNICODE e _MBCS não definidos |
_MBCS definido |
_UNICODE definido |
|---|---|---|---|
_vsntprintf |
_vsnprintf |
_vsnprintf |
_vsnwprintf |
_vsntprintf_l |
_vsnprintf_l |
_vsnprintf_l |
_vsnwprintf_l |
Requerimentos
| Rotina | Cabeçalho obrigatório (C) | Cabeçalho obrigató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> |
O _vsnprintf, _vsnprintf_l_vsnwprintf e _vsnwprintf_l as funções são específicas da Microsoft. Para obter mais informações sobre compatibilidade, consulte Compatibilidade.
Exemplo: Use 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 muda se você usar vsnprintf em vez disso, juntamente com parâmetros de cadeia de caracteres estreita. O count parâmetro pode ser o tamanho inteiro do buffer, e o valor de retorno é 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!
Ver também
de E/S de fluxo
vprintf funções
Sintaxe da especificação do formato: printf e wprintf funções
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