fprintf, sprintf y snprintf

Cerramos esta temporada presentando fprintf, sprintf y snprintf, tres funciones parecidas a printf pero que se diferencian en dónde vuelcan lo que van formateando. fprintf permite volcar con formato en archivos y sprintf/snprintf en cadenas de caracteres.

En el mundo de la programación en C, manejar la salida de datos con formato es una tarea común que podemos abordar de distintas maneras según el contexto. Dos funciones que nos facilitan esta labor y que merecen más atención son fprintf y sprintf, ambas estrechamente relacionadas con la conocida printf, pero con aplicaciones específicas que las hacen muy útiles.

Comenzamos con fprintf, que es básicamente una versión de printf orientada a archivos. En lugar de enviar la salida a la consola, fprintf nos permite escribir texto formateado directamente en un archivo que hayamos abierto previamente con fopen. Por ejemplo, si abrimos un archivo llamado lineas.txt en modo escritura, podemos usar fprintf para volcar en él cadenas con formato, como si estuviéramos usando printf, pero apuntando al archivo en lugar de a la salida estándar. Esto resulta especialmente práctico para generar archivos de texto con contenido estructurado sin complicarnos con funciones más básicas como fputs o fputc. Al cerrar el archivo con fclose, el contenido queda guardado y listo para ser consultado, mostrando exactamente la cadena formateada que hemos especificado.

Un detalle interesante es que printf podría considerarse una especie de primo pequeño de fprintf, ya que internamente es equivalente a usar fprintf con el archivo estándar de salida stdout. Esto nos ayuda a entender mejor la relación entre estas funciones y cómo podemos elegir la más adecuada según dónde queramos enviar la salida.

Por otro lado, sprintf es una función que nos encanta por su versatilidad para construir cadenas de texto con formato dentro de nuestro programa. En lugar de imprimir en pantalla o en un archivo, sprintf escribe la salida formateada en una cadena de caracteres que nosotros proporcionamos. Esto es muy útil cuando necesitamos crear mensajes complejos o concatenar datos de forma ordenada sin complicarnos con funciones de manipulación de strings más engorrosas.

Por ejemplo, podemos declarar un arreglo de caracteres llamado output con una longitud suficiente, digamos 80 caracteres, y luego usar sprintf para volcar en él una frase con variables insertadas, como una fecha. Así, si tenemos variables para día, mes y año, podemos construir una cadena que diga “Hoy es 19 del 11 del 2020” y luego imprimir esa cadena con un simple printf. Esto simplifica mucho la creación de textos dinámicos dentro del programa.

Sin embargo, hay que tener mucho cuidado con sprintf porque no realiza ninguna comprobación sobre el tamaño del buffer donde escribe. Si la cadena que intentamos formar es más larga que el espacio reservado, se produce un desbordamiento de buffer, un error grave que puede corromper la memoria y causar fallos en el programa. Algunos compiladores modernos detectan este problema y nos avisan, pero no siempre es así, por lo que debemos ser precavidos.

Para evitar este riesgo, existe la función snprintf, que es una variante segura de sprintf. La diferencia principal es que snprintf recibe un parámetro adicional que indica el tamaño máximo del buffer donde se va a escribir. De esta forma, la función se asegura de no escribir más allá de ese límite, evitando desbordamientos. Aunque si el texto formateado es demasiado largo, la cadena resultante se truncará, pero al menos el programa seguirá siendo seguro.

Por ejemplo, si nuestro buffer tiene espacio para 10 caracteres, podemos llamar a snprintf indicando ese límite, y la función se encargará de no excederlo. Esto es especialmente importante en programas donde la seguridad y la estabilidad son prioritarias, y donde no podemos permitirnos errores de memoria.

En definitiva, estas funciones nos ofrecen herramientas muy potentes para manejar texto con formato en C, ya sea para escribir en archivos o para construir cadenas dinámicas dentro del programa. Adoptar el uso de fprintf para archivos y preferir snprintf sobre sprintf para evitar problemas de seguridad nos ayudará a escribir código más limpio, eficiente y seguro.

Lista de reproducción
  1. 1
    Instalar CodeBlocks
    15 minutos
  2. 2
    Funciones y hola mundo
    17 minutos
  3. 3
    Variables y tipos de datos
    17 minutos
  4. 4
    Condicionales y operadores lógicos
    16 minutos
  5. 5
    Bucles
    11 minutos
  6. 6
    Punteros
    12 minutos
  7. 7
    Arrays
    14 minutos
  8. 8
    Estructuras
    12 minutos
  9. 9
    Otras construcciones de C
    9 minutos
  10. 10
    Memoria dinámica
    8 minutos
  11. 11
    El preprocesador (parte 1)
    10 minutos
  12. 12
    El preprocesador (parte 2)
    9 minutos
  13. 13
    Archivos de cabecera y múltiples .c (parte 1)
    8 minutos
  14. 14
    Archivos de cabecera y múltiples .c (parte 2)
    9 minutos
  15. 15
    C desde la línea de comandos (parte 1)
    8 minutos
  16. 16
    C desde la línea de comandos (parte 2)
    9 minutos
  17. 17
    Break y continue
    10 minutos
  18. 18
    Goto
    13 minutos
  19. 19
    Manipulación de bits
    15 minutos
  20. 20
    Máscaras de bit
    19 minutos
  21. 21
    Archivos (1): fopen y fclose
    13 minutos
  22. 22
    Archivos (2): leer con fgetc
    9 minutos
  23. 23
    Archivos (3): fseek y ftell
    11 minutos
  24. 24
    Archivos (4): leer con fgets
    9 minutos
  25. 25
    Archivos (5): fputc y fputs
    7 minutos
  26. 26
    Archivos (6): volcar en archivos con fwrite
    10 minutos
  27. 27
    Archivos (7): fread, fwrite y los arrays
    10 minutos
  28. 28
    Archivos (8): entrada estándar y salida estándar
    9 minutos
  29. 29
    Archivos (9): buffers
    14 minutos
  30. 30
    Archivos (y 10): otras funciones útiles con archivos
    5 minutos
  31. 31
    printf (1)
    18 minutos
  32. 32
    printf (parte 2)
    12 minutos
  33. 33
    scanf (parte 1)
    17 minutos
  34. 34
    scanf (parte 2)
    17 minutos
  35. 35
    fprintf, sprintf y snprintf
    8 minutos
  36. 36
    Tipos de datos opacos
    13 minutos
  37. 37
    Bibliotecas estáticas
    13 minutos
  38. 38
    Bibliotecas dinámicas
    15 minutos
  39. 39
    Más flags: i mayúscula (include), wall, werror, pedantic...
    12 minutos
  40. 40
    pkg-config
    12 minutos
  41. 41
    Make
    17 minutos
  42. 42
    GDB
    21 minutos
  43. 43
    Variables globales
    6 minutos
  44. 44
    extern
    9 minutos
  45. 45
    Funciones variádicas
    12 minutos
  46. 46
    El optimizador de GCC y la opción -O
    12 minutos
  47. 47
    Volatile
    6 minutos