Compartir a través de


snprintf, _snprintf, _snprintf_l, , _snwprintf, _snwprintf_l

Escribe datos con formato en una cadena. Hay disponibles versiones más seguras de estas funciones; consulte _snprintf_s, _snprintf_s_l, _snwprintf_s, _snwprintf_s_l.

Sintaxis

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

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

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

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

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

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

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

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

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

Parámetros

buffer
Ubicación de almacenamiento del resultado.

count
Número máximo de caracteres que se van a escribir. Para las funciones que toman wchar_t, es el número máximo de caracteres anchos que se van a escribir.

format
Cadena de control de formato.

argument
Argumentos opcionales.

locale
Configuración regional que se va a usar para dar formato a la salida.

Para obtener más información, consulte Sintaxis de especificación de formato: printf y wprintf funciones.

Valor devuelto

Número de caracteres que se habrían escrito en el búfer si count se omite. El recuento no incluye el carácter de NULL terminación.

Deje que len sea la longitud de la cadena de datos con formato, no incluida la terminación NULL.
Para todas las funciones, si len < count, los len caracteres se almacenan en buffer, se anexa un terminador null y se devuelve el número de caracteres escritos, no incluido el terminador NULL.

Las versiones de caracteres anchos de estas funciones devuelven el número de caracteres anchos escritos, no incluida la terminación NULL.

Consulte Resumen del comportamiento para obtener más información.

Comentarios

A partir del UCRT en Visual Studio 2015 y Windows 10, la palabra clave snprintf ya no es idéntica a _snprintf. El snprintf comportamiento es ahora compatible con el estándar C99. La diferencia es que si se agota el búfer, snprintf null finaliza el final del búfer y devuelve el número de caracteres que se habrían requerido, mientras _snprintf que no termina en null el búfer y devuelve -1. Además, snprintf() incluye un carácter más en la salida porque no finaliza con null el búfer.

  • snprintf y la _snprintf familia de funciones formatear y almacenar count o menos caracteres en buffer.
  • snprintf siempre almacena un carácter de terminación NULL , truncando la salida si es necesario.
  • Si snprintf devuelve un valor >count - 1, la salida se ha truncado.
  • La _snprintf familia de funciones solo anexa un carácter de terminación NULL si la longitud de cadena con formato es estrictamente menor que count los caracteres.
  • Cada argument (si existe) se convierte y se muestra según la especificación de formato correspondiente de format. El formato consta de caracteres ordinarios y tiene el mismo formato y función que el argumento format para printf. Si la copia tiene lugar entre cadenas que se superponen, el comportamiento es indefinido.

Resumen del comportamiento

Para la tabla siguiente:

  • Deje que sizeOfBuffer sea el tamaño de buffer. Si la función toma un char búfer, el tamaño está en bytes. Si la función toma un wchar_t búfer, el tamaño especifica el número de palabras de 16 bits.
  • Vamos len a ser el tamaño de los datos con formato. Si la función toma un char búfer, el tamaño está en bytes. Si la función toma un wchar_t búfer, el tamaño especifica el número de palabras de 16 bits.
  • Los caracteres hacen referencia a char caracteres para funciones que toman un char búfer y a wchar_t caracteres para las funciones que toman un wchar_t búfer.
  • Para obtener más información sobre el controlador de parámetros no válidos, vea Validación de parámetros.
Condición Comportamiento Valor devuelto errno Invoca el controlador de parámetros no válidos
Correcto Escribe los caracteres en el búfer mediante la cadena de formato especificada. El número de caracteres que se han escrito. N/D No
Error de codificación durante el formato Si el especificador sde cadena de procesamiento , So Z, detiene el procesamiento de la especificación de formato, se coloca al NULL principio del búfer. -1 EILSEQ (42) No
Error de codificación durante el formato Si el especificador c de caracteres de procesamiento o C, se omite el carácter no válido. El número de caracteres escritos no se incrementa para el carácter omitido, ni es ningún dato escrito para él. El procesamiento de la especificación de formato continúa después de omitir el especificador con el error de codificación. Número de caracteres escritos, no incluido el terminador NULL. EILSEQ (42) No
buffer == NULL y count != 0 Si la ejecución continúa después de que se ejecute el controlador de parámetros no válidos, establece errno y devuelve un valor negativo. -1 EINVAL (22)
count == 0 Número de caracteres que se habrían escrito, no incluido el terminador NULL. Puede usar este resultado para asignar suficiente espacio de búfer para la cadena y un terminado NULLy, a continuación, llamar a la función de nuevo para rellenar el búfer. N/D No
count < 0 No seguro: el valor se trata como sin firmar, lo que probablemente crea un valor grande que da lugar a sobrescribir la memoria que sigue al búfer. Número de caracteres escritos N/D No
count < sizeOfBuffer y len <= count Todos los datos se escriben y se anexa una terminación NULL . Número de caracteres escritos, no incluido el terminador NULL. N/D No
count < sizeOfBuffer y len > count Los primeros count-1 caracteres se escriben seguidos de un terminador null. El número de caracteres que se habrían escrito coincidía count con el número de caracteres que se van a generar, no incluido el terminador null. N/D No
count >= sizeOfBuffer y len < sizeOfBuffer Todos los datos se escriben NULLcon una terminación . Número de caracteres escritos, no incluido el terminador NULL. N/D No
count >= sizeOfBuffer y len >= sizeOfBuffer No seguro: sobrescribe la memoria que sigue al búfer. Número de caracteres escritos, no incluido el terminador NULL. N/D No
format == NULL No se escriben datos. Si la ejecución continúa después de que se ejecute el controlador de parámetros no válidos, establece errno y devuelve un valor negativo. -1 EINVAL (22)

Para información sobre estos y otros códigos de error, consulte _doserrno, errno_sys_errlist y _sys_nerr.

Importante

Asegúrese de que format no es una cadena definida por el usuario. Puesto que las funciones _snprintf no garantizan la terminación nula, en concreto, cuando el valor devuelto es count, hay que asegurarse de que vayan seguidas de código que agregue el terminador nulo. Para obtener más información, consulte Evitar saturaciones del búfer.

A partir de Windows 10 versión 2004 (compilación 19041), la familia de funciones printf imprime números de punto flotante que se pueden representar con exactitud según las reglas de redondeo de IEEE 754. En versiones anteriores de Windows, los números de punto flotante que se pueden representar de forma exacta y terminan en "5" siempre se redondean al alza. IEEE 754 indica que deben redondearse al dígito par más próximo (también conocido como "redondeo bancario"). Por ejemplo, tanto printf("%1.0f", 1.5) como printf("%1.0f", 2.5) deben redondearse a 2. Anteriormente, 1,5 se redondearía a 2 y 2,5 a 3. Este cambio solo afecta a los números que se pueden representar de forma exacta. Por ejemplo, 2,35 (que, cuando se representa en memoria, está más cerca de 2,35000000000000008) se sigue redondeando hasta 2,4. El redondeo realizado por estas funciones ahora también respeta el modo de redondeo de punto flotante que fesetround establece. Anteriormente, el redondeo siempre elegía el comportamiento FE_TONEAREST. Este cambio solo afecta a los programas compilados con Visual Studio 2019 versión 16.2 y posteriores. Para usar el comportamiento de redondeo de punto flotante heredado, establezca un vínculo con legacy_stdio_float_rounding.obj.

_snwprintf es una versión con caracteres anchos de _snprintf; los argumentos de puntero a _snwprintf son cadenas de carácter ancho. La detección de errores de codificación en _snwprintf puede diferir de la detección en _snprintf. _snwprintf, como swprintf, escribe el resultado en una cadena en lugar de hacerlo en un destino de tipo FILE.

Las versiones de estas funciones que tienen el sufijo _l son idénticas salvo que usan el parámetro de configuración regional que se pasa en lugar de la configuración regional del subproceso actual.

En C++, estas funciones tienen sobrecargas de plantilla que invocan a los homólogos más recientes y seguros. Para obtener más información, consulte Sobrecargas de plantilla seguras.

Asignaciones de rutinas de texto genérico

Rutina Tchar.h _UNICODE y _MBCS no definidos _MBCS definido _UNICODE definido
_sntprintf _snprintf _snprintf _snwprintf
_sntprintf_l _snprintf_l _snprintf_l _snwprintf_l

Requisitos

Routine Encabezado necesario
snprintf, , _snprintf, _snprintf_l <stdio.h>
_snwprintf, _snwprintf_l <stdio.h> o <wchar.h>

Para obtener más información sobre compatibilidad, consulte Compatibilidad.

Ejemplo

// crt_snprintf.c
// compile with: /W3
#include <stdio.h>
#include <stdlib.h>

#if !defined(__cplusplus)
typedef int bool;
const bool true = 1;
const bool false = 0;
#endif

#define FAIL 0 // change to 1 and see what happens

int main(void)
{
   char buffer[200];
   const static char s[] = "computer"
#if FAIL
"computercomputercomputercomputercomputercomputercomputercomputer"
"computercomputercomputercomputercomputercomputercomputercomputer"
"computercomputercomputercomputercomputercomputercomputercomputer"
"computercomputercomputercomputercomputercomputercomputercomputer"
#endif
   ;
   const char c = 'l';
   const int i = 35;
#if FAIL
   const double fp = 1e300; // doesn't fit in the buffer
#else
   const double fp = 1.7320534;
#endif
   /* !subtract one to prevent "squeezing out" the terminal null! */
   const int bufferSize = sizeof(buffer)/sizeof(buffer[0]) - 1;
   int bufferUsed = 0;
   int bufferLeft = bufferSize - bufferUsed;
   bool bSuccess = true;
   buffer[0] = 0;

   /* Format and print various data: */

   if (bufferLeft > 0)
   {
      int perElementBufferUsed = _snprintf(&buffer[bufferUsed],
      bufferLeft, "   String: %s\n", s ); // C4996
      // Note: _snprintf is deprecated; consider _snprintf_s instead
      if (bSuccess = (perElementBufferUsed >= 0))
      {
         bufferUsed += perElementBufferUsed;
         bufferLeft -= perElementBufferUsed;
         if (bufferLeft > 0)
         {
            int perElementBufferUsed = _snprintf(&buffer[bufferUsed],
            bufferLeft, "   Character: %c\n", c ); // C4996
            if (bSuccess = (perElementBufferUsed >= 0))
            {
               bufferUsed += perElementBufferUsed;
               bufferLeft -= perElementBufferUsed;
               if (bufferLeft > 0)
               {
                  int perElementBufferUsed = _snprintf(&buffer
                  [bufferUsed], bufferLeft, "   Integer: %d\n", i ); // C4996
                  if (bSuccess = (perElementBufferUsed >= 0))
                  {
                     bufferUsed += perElementBufferUsed;
                     bufferLeft -= perElementBufferUsed;
                     if (bufferLeft > 0)
                     {
                        int perElementBufferUsed = _snprintf(&buffer
                        [bufferUsed], bufferLeft, "   Real: %f\n", fp ); // C4996
                        if (bSuccess = (perElementBufferUsed >= 0))
                        {
                           bufferUsed += perElementBufferUsed;
                        }
                     }
                  }
               }
            }
         }
      }
   }

   if (!bSuccess)
   {
      printf("%s\n", "failure");
   }
   else
   {
      /* !store null because _snprintf doesn't necessarily (if the string
       * fits without the terminal null, but not with it)!
       * bufferUsed might be as large as bufferSize, which normally is
       * like going one element beyond a buffer, but in this case
       * subtracted one from bufferSize, so we're ok.
       */
      buffer[bufferUsed] = 0;
      printf( "Output:\n%s\ncharacter count = %d\n", buffer, bufferUsed );
   }
   return EXIT_SUCCESS;
}
Output:
   String: computer
   Character: l
   Integer: 35
   Real: 1.732053

character count = 69

Vea también

E/S de secuencia
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
Funciones vprintf