sprintf y snprintf en C: ejercicio resuelto

sprintf y snprintf en C: ejercicio resuelto

Si buscas sprintf y snprintf en C ejercicio resuelto, aquí tienes los patrones más habituales: formatear números en cadenas, construir rutas de fichero dinámicamente y combinar campos en un único buffer, con la diferencia clave entre sprintf (sin límite) y snprintf (con límite seguro).

snprintf es la versión segura que nunca escribe más de n bytes incluyendo el terminador \0. En código moderno siempre se prefiere snprintf frente a sprintf.

Enunciado

  1. Usa sprintf para construir la cadena "Resultado: 42 (0x2A)".
  2. Usa snprintf para construir rutas con el patrón "/logs/dia_03.log".
  3. Detecta el truncamiento cuando el buffer es demasiado pequeño.

Solución en C

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <stdio.h>
#include <string.h>

int main(void) {
    char buf[64];

    /* 1. sprintf: número decimal y hexadecimal */
    sprintf(buf, "Resultado: %d (0x%X)", 42, 42);
    printf("%s\n", buf);

    /* 2. snprintf: construir rutas de forma segura */
    for (int dia = 1; dia <= 3; dia++) {
        snprintf(buf, sizeof(buf), "/logs/dia_%02d.log", dia);
        printf("Ruta: %s\n", buf);
    }

    /* 3. Detectar truncamiento */
    char pequeño[10];
    int escrito = snprintf(pequeño, sizeof(pequeño), "Cadena muy larga: %d", 12345);
    if (escrito >= (int)sizeof(pequeño)) {
        printf("Truncado: necesitaba %d bytes, buffer de %zu\n",
               escrito, sizeof(pequeño));
    }
    printf("Buffer: \"%s\"\n", pequeño);

    return 0;
}

Resultado esperado

1
2
3
4
5
6
Resultado: 42 (0x2A)
Ruta: /logs/dia_01.log
Ruta: /logs/dia_02.log
Ruta: /logs/dia_03.log
Truncado: necesitaba 22 bytes, buffer de 10
Buffer: "Cadena mu"

Errores frecuentes

  • Usar sprintf con buffers de tamaño fijo: si el texto formateado supera el tamaño del buffer, se produce un desbordamiento de buffer (undefined behavior y vulnerabilidad de seguridad).
  • No comprobar el valor de retorno de snprintf: devuelve el número de bytes que se habrían escrito sin el límite; si es >= n, hay truncamiento.
  • Confundir snprintf con strncpy: snprintf siempre termina con \0; strncpy no lo garantiza si la cadena fuente es más larga que n.
  • Olvidar el \0 en el cálculo del tamaño: snprintf(buf, 10, ...) deja espacio para 9 caracteres más el terminador.

Aplicación práctica

snprintf es la función estándar para construir cadenas formateadas en C: nombres de fichero, mensajes de log, respuestas HTTP de texto plano y cualquier escenario donde se combinen datos numéricos y texto. Es la alternativa segura a la concatenación manual con strcat.

Siguiente ejercicio recomendado

Práctica guiada y libro completo

Si quieres una ruta completa con progresión real de dificultad:

FAQ

¿Qué devuelve snprintf exactamente?

Devuelve el número de bytes que se habrían escrito si el buffer fuera suficientemente grande, sin contar el \0 final. Si el valor devuelto es >= n (el tamaño del buffer), la cadena fue truncada y hay que aumentar el buffer o gestionar el truncamiento.

¿Por qué sprintf es considerado inseguro?

Porque no tiene límite de escritura. Si el texto formateado supera el tamaño del buffer, sprintf escribe más allá del límite, corrompiendo memoria adyacente. Esto es un desbordamiento de buffer, que en código de red o con entradas externas es una vulnerabilidad explotable.

¿Existe alguna alternativa más moderna?

En C11 existe sprintf_s y snprintf_s (extensiones opcionales del Anexo K), pero su adopción es limitada. La práctica estándar es usar snprintf con sizeof(buffer) siempre.