Compartilhar via


_snprintf_s, _snprintf_s_l, _snwprintf_s, _snwprintf_s_l

Grava dados formatados em uma cadeia de caracteres. Essas funções são versões de , _snprintf, _snprintf_l, _snwprintf _snwprintf_l, com aprimoramentos de snprintfsegurança descritos em Recursos de segurança no CRT.

Sintaxe

int _snprintf_s(
   char *buffer,
   size_t sizeOfBuffer,
   size_t count,
   const char *format [,
   argument] ...
);

int _snprintf_s_l(
   char *buffer,
   size_t sizeOfBuffer,
   size_t count,
   const char *format,
   _locale_t locale [,
   argument] ...
);

int _snwprintf_s(
   wchar_t *buffer,
   size_t sizeOfBuffer,
   size_t count,
   const wchar_t *format [,
   argument] ...
);

int _snwprintf_s_l(
   wchar_t *buffer,
   size_t sizeOfBuffer,
   size_t count,
   const wchar_t *format,
   _locale_t locale [,
   argument] ...
);

template <size_t size>
int _snprintf_s(
   char (&buffer)[size],
   size_t count,
   const char *format [,
   argument] ...
); // C++ only

template <size_t size>
int _snwprintf_s(
   wchar_t (&buffer)[size],
   size_t count,
   const wchar_t *format [,
   argument] ...
); // C++ only

Parâmetros

buffer
Local de armazenamento para a saída.

sizeOfBuffer
O tamanho do local de armazenamento para a saída. Tamanho em bytes para as funções que levam char, e palavras para aquelas que levam wchar_t.

count
O número máximo de caracteres a serem gravados. Para as funções que usam wchar_t, é o número máximo de caracteres largos a serem gravados. Ou _TRUNCATE.

format
Cadeia de caracteres de controle de formato.

argument
Argumentos opcionais.

locale
A localidade a ser usada.

Valor retornado

O número de caracteres escritos, sem incluir o .NULL Um valor negativo será retornado se ocorrer um erro de saída. Consulte Resumo do comportamento para obter detalhes.

Comentários

A _snprintf_s função formata e armazena count ou menos caracteres e buffer acrescenta um NULL. Cada argumento (se houver) é convertido e gerado de acordo com a especificação de formato correspondente em format. A formatação é consistente com a printf família de funções; consulte Sintaxe de especificação de formato: printf e wprintf funções. Se ocorrer cópia entre cadeias de caracteres que se sobrepõem, o comportamento será indefinido.

Resumo do comportamento

Para a tabela a seguir:

-Seja len o tamanho dos dados formatados. Se a função usar um char buffer, o tamanho será em bytes. Se a função usar um wchar_t buffer, o tamanho especificará o número de palavras de 16 bits.

  • Caracteres referem-se a char caracteres para funções que usam um char buffer e a wchar_t caracteres para funções que usam um wchar_t buffer.
  • Para obter mais informações sobre o manipulador de parâmetro inválido, consulte Validação de parâmetro.
Condição Comportamento 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 incluir o .NULL N/D Não
Erro de codificação durante a formatação Se o especificador sde cadeia de caracteres de processamento , 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 estiver processando especificador c de caracteres ou C, o caractere inválido será ignorado. O número de caracteres gravados não é incrementado para o caractere ignorado, nem nenhum dado é gravado 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, sem incluir o .NULL EILSEQ (42) Não
buffer == NULL e sizeOfBuffer == 0 e count == 0 Nenhum dado é gravado. 0 N/D Não
buffer == NULLe ou sizeOfBuffer != 0count != 0 Se a execução continuar após a execução do manipulador de parâmetros inválidos, definirá errno e retornará um valor negativo. -1 EINVAL (22) Sim
buffer != NULL e sizeOfBuffer == 0 Nenhum dado é gravado. -1 EINVAL (22) Sim
count == 0 A NULL é colocado no início do buffer. -1 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 escritos, sem incluir o .NULL N/D 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/D Não
count < sizeOfBuffer e len > count Os primeiros count caracteres são gravados e uma terminação NULL é anexada. -1 N/D Não
count >= sizeOfBuffer e len < sizeOfBuffer Todos os dados são gravados com um .NULL O número de caracteres gravados. N/D Não
count >= sizeOfBuffer e len >= sizeOfBuffer e count != _TRUNCATE Se a execução continuar após a execução do manipulador de parâmetros inválidos, definirá errno, definirá buffer[0] == NULLe retornará um valor negativo. -1 ERANGE (34) Sim
count == _TRUNCATE e len >= sizeOfBuffer Grava o máximo da string que couber e buffer um .NULL -1 N/D Não
count == _TRUNCATE e len < sizeOfBuffer Grava a string inteira com buffer um .NULL Número de caracteres escritos, não incluindo a terminação 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álidos, 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.

Importante

Verifique se format não é uma cadeia de caracteres definida pelo usuário.

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'.

_snwprintf_s é uma versão de caractere largo de _snprintf_s; os argumentos de ponteiro para _snwprintf_s são cadeias de caracteres largos. A detecção de erros de codificação em _snwprintf_s pode ser diferente da detecção em _snprintf_s. _snwprintf_s, assim como swprintf_s, grava o resultado em uma cadeia de caracteres em vez de em um destino do tipo FILE.

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.

Em C++, o uso dessas funções é simplificado pelas sobrecargas de modelo; as sobrecargas podem inferir o tamanho do buffer automaticamente (eliminando a necessidade de especificar um argumento de tamanho) e podem substituir automaticamente funções mais antigas e não seguras por suas equivalentes mais recentes e seguras. Para obter mais informações, consulte Sobrecargas de modelo seguras.

Mapeamentos de rotina de texto genérico

Rotina Tchar.h _UNICODE e _MBCS não definidos _MBCS definido _UNICODE definido
_sntprintf_s _snprintf_s _snprintf_s _snwprintf_s
_sntprintf_s_l _snprintf_s_l _snprintf_s_l _snwprintf_s_l

Requisitos

Rotina Cabeçalho necessário
_snprintf_s, _snprintf_s_l <stdio.h>
_snwprintf_s, _snwprintf_s_l <stdio.h> ou <wchar.h>

Para obter informações sobre compatibilidade, consulte Compatibilidade.

Exemplo

// crt_snprintf_s.cpp
// compile with: /MTd

// These #defines enable secure template overloads
// (see last part of Examples() below)
#define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES 1
#define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_COUNT 1

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <crtdbg.h>  // For _CrtSetReportMode
#include <errno.h>

// This example uses a 10-byte destination buffer.

int snprintf_s_tester( const char * fmt, int x, size_t count )
{
   char dest[10];

   printf( "\n" );

   if ( count == _TRUNCATE )
      printf( "%zd-byte buffer; truncation semantics\n",
               _countof(dest) );
   else
      printf( "count = %zd; %zd-byte buffer\n",
               count, _countof(dest) );

   int ret = _snprintf_s( dest, _countof(dest), count, fmt, x );

   printf( "    new contents of dest: '%s'\n", dest );

   return ret;
}

void Examples()
{
   // formatted output string is 9 characters long: "<<<123>>>"
   snprintf_s_tester( "<<<%d>>>", 121, 8 );
   snprintf_s_tester( "<<<%d>>>", 121, 9 );
   snprintf_s_tester( "<<<%d>>>", 121, 10 );

   printf( "\nDestination buffer too small:\n" );

   snprintf_s_tester( "<<<%d>>>", 1221, 10 );

   printf( "\nTruncation examples:\n" );

   int ret = snprintf_s_tester( "<<<%d>>>", 1221, _TRUNCATE );
   printf( "    truncation %s occur\n", ret == -1 ? "did"
                                                  : "did not" );

   ret = snprintf_s_tester( "<<<%d>>>", 121, _TRUNCATE );
   printf( "    truncation %s occur\n", ret == -1 ? "did"
                                                  : "did not" );
   printf( "\nSecure template overload example:\n" );

   char dest[10];
   _snprintf( dest, 10, "<<<%d>>>", 12321 );
   // With secure template overloads enabled (see #defines
   // at top of file), the preceding line is replaced by
   //    _snprintf_s( dest, _countof(dest), 10, "<<<%d>>>", 12345 );
   // Instead of causing a buffer overrun, _snprintf_s invokes
   // the invalid parameter handler.
   // If secure template overloads were disabled, _snprintf would
   // write 10 characters and overrun the dest buffer.
   printf( "    new contents of dest: '%s'\n", dest );
}

void myInvalidParameterHandler(
   const wchar_t* expression,
   const wchar_t* function,
   const wchar_t* file,
   unsigned int line,
   uintptr_t pReserved)
{
   wprintf(L"Invalid parameter handler invoked: %s\n", expression);
}

int main( void )
{
   _invalid_parameter_handler oldHandler, newHandler;

   newHandler = myInvalidParameterHandler;
   oldHandler = _set_invalid_parameter_handler(newHandler);
   // Disable the message box for assertions.
   _CrtSetReportMode(_CRT_ASSERT, 0);

   Examples();
}

count = 8; 10-byte buffer
    new contents of dest: '<<<121>>'

count = 9; 10-byte buffer
    new contents of dest: '<<<121>>>'

count = 10; 10-byte buffer
    new contents of dest: '<<<121>>>'

Destination buffer too small:

count = 10; 10-byte buffer
Invalid parameter handler invoked: ("Buffer too small", 0)
    new contents of dest: ''

Truncation examples:

10-byte buffer; truncation semantics
    new contents of dest: '<<<1221>>'
    truncation did occur

10-byte buffer; truncation semantics
    new contents of dest: '<<<121>>>'
    truncation did not occur

Secure template overload example:
Invalid parameter handler invoked: ("Buffer too small", 0)
    new contents of dest: ''

Confira também

E/S de fluxo
sprintf, _sprintf_l, swprintf, _swprintf_l, __swprintf_l
fprintf, _fprintf_l, fwprintf, _fwprintf_l
printf, _printf_l, wprintf, _wprintf_l
scanf, _scanf_l, wscanf, _wscanf_l
sscanf, _sscanf_l, swscanf, _swscanf_l
Funções vprintf