Archivos (3): fseek y ftell

fseek y ftell son un par de primitivas que forman stdio y que nos permiten desplazar el cursor a lo largo de un archivo para poder determinar qué será leído o dónde será escrito cuando usemos las primitivas de lectura y escritura de la API de archivos de C.

Cuando trabajamos con archivos en C, es fundamental entender cómo se maneja el cursor, ese indicador que nos muestra dónde se va a leer o escribir en el archivo. Este cursor funciona de manera similar a la línea parpadeante que vemos en un editor de texto, señalando la posición actual dentro del archivo. Para manipularlo y obtener información sobre su ubicación, contamos con funciones muy útiles como ftell y fseek.

La función ftell nos permite conocer la posición actual del cursor dentro del archivo. Recibe como parámetro el descriptor del archivo y devuelve un valor de tipo long que indica la posición en bytes desde el inicio del archivo. Por ejemplo, si abrimos un archivo en modo lectura, el cursor estará al principio y ftell devolverá cero. En cambio, si abrimos el archivo en modo append, el cursor se posicionará al final, y ftell nos devolverá el tamaño del archivo en bytes, que corresponde a la posición del cursor. Es importante tener en cuenta que si ftell devuelve -1, significa que ha ocurrido un error al obtener la posición.

Para ilustrar cómo funciona ftell, podemos leer un archivo carácter a carácter con fgetc y, en cada iteración, imprimir la posición actual del cursor junto con el carácter leído. Esto nos permite ver cómo avanza el cursor a medida que recorremos el archivo.

Por otro lado, la función fseek nos da la capacidad de mover el cursor a una posición específica dentro del archivo. Esta función recibe tres parámetros: el descriptor del archivo, un desplazamiento (offset) y un modo que indica desde dónde se realiza ese desplazamiento. Los modos posibles son SEEK_SET, que mueve el cursor a una posición relativa al inicio del archivo; SEEK_END, que lo mueve relativo al final del archivo; y SEEK_CUR, que lo mueve relativo a la posición actual del cursor. Por ejemplo, con fseek(file, 5, SEEK_SET) posicionamos el cursor en el byte número 5 desde el inicio, mientras que con fseek(file, -5, SEEK_END) lo colocamos cinco bytes antes del final.

Una aplicación práctica de estas funciones es calcular el tamaño de un archivo. Para ello, abrimos el archivo en modo lectura, usamos fseek para mover el cursor al final (SEEK_END), luego llamamos a ftell para obtener la posición actual, que corresponde al tamaño en bytes, y finalmente usamos rewind para regresar el cursor al inicio del archivo. La función rewind es equivalente a llamar a fseek con desplazamiento cero y modo SEEK_SET.

Sin embargo, hay que tener precaución con este método cuando trabajamos con archivos de texto en sistemas Windows. Esto se debe a que los saltos de línea en Windows se representan con dos caracteres (\r\n), mientras que en otros sistemas suelen ser solo uno (\n). Los runtimes de C en Windows suelen interpretar estos dos caracteres como un solo salto de línea al leer el archivo, lo que puede hacer que la posición del cursor reportada por ftell no coincida con el tamaño real en bytes del archivo. Para evitar este problema, es recomendable abrir el archivo en modo binario (rb), lo que desactiva esta interpretación y permite que ftell y fseek funcionen correctamente para calcular tamaños y posicionar el cursor.

En resumen, ftell, fseek y rewind son herramientas esenciales para controlar la posición del cursor en archivos, especialmente cuando trabajamos con archivos binarios o necesitamos manipular la lectura y escritura de manera precisa. No obstante, debemos ser conscientes de las particularidades del sistema operativo y el modo en que abrimos los archivos para evitar resultados inesperados.

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