Herramienta de línea de comandos desarrollada en lenguaje C para convertir datos meteorológicos almacenados en formato binario estructurado hacia un archivo de texto tipo CSV.
Este proyecto demuestra:
- Lectura y parsing de archivos binarios mediante estructuras (
struct) - Procesamiento eficiente bajo restricción de memoria (una estructura por iteración)
- Manejo de memoria dinámica
- Parseo de argumentos por línea de comandos
- Normalización de timestamps (época 2000 → época UNIX)
- Gestión robusta de archivos
- Generación formateada de archivos CSV
- Descripción General
- Especificación del Formato Binario
- Interpretación del problema
- Librerías incorporadas
- Solución
- Desglose del programa
- Modo de uso
- Diagrama de flujo
- Referencias
El programa implementa un conversor de datos meteorológicos almacenados en formato binario estructurado hacia un archivo CSV.
El diseño está orientado a:
- Procesamiento eficiente de archivos potencialmente grandes sin carga completa en memoria.
- Conversión precisa de datos escalados (valores almacenados multiplicados por 10).
- Manejo correcto de timestamps definidos desde una época distinta a la UNIX.
- Interfaz flexible mediante línea de comandos.
- Independencia del directorio del archivo fuente.
Se trata de una herramienta CLI completamente funcional, desarrollada exclusivamente con librerías estándar del lenguaje C.
Los datos del archivo binario están organizados como estructuras consecutivas con el siguiente layout:
UINT32 Identificación de estación
UINT16 Presión *10 (milibares)
INT16 Temperatura *10 (grados centígrados)
UINT16 Precipitaciones caídas *10 (milímetros)
UINT8 Humedad relativa ambiente en %
UINT32 Fecha y Hora de medición en segundos desde 01/01/2000 00:00:00
El programa asume que el archivo respeta exactamente esta disposición en memoria.
El archivo CSV generado contiene los siguientes campos:
- Identificación de estación
- Fecha (dd/mm/yyyy)
- Hora (hh:mm:ss)
- Temperatura (TT.t °C)
- Presión (PPPP.p mbar)
- Precipitaciones (zzz.u mm)
- Humedad (%)
El procesamiento se realiza bajo la restricción de no almacenar más de una estructura en memoria simultáneamente.
Esto implica un modelo de procesamiento basado en flujo (streaming), leyendo una estación por iteración mediante fread().
A partir de la especificación del formato binario, el objetivo principal es implementar un programa en C capaz de:
- Leer registros estructurados directamente desde un archivo binario.
- Reconstruir correctamente los tipos de datos.
- Reescalar valores almacenados como enteros multiplicados por 10.
- Convertir timestamps desde época 2000 a época UNIX.
- Exportar los datos en formato CSV correctamente formateado.
Se establece como interfaz usuario-programa la terminal de comandos.
El programa soporta dos modos de funcionamiento:
- Modo simple: archivo binario en el directorio actual.
- Modo extendido: especificación explícita de directorio mediante flag
-cd.
En cuanto a los tipos de datos utilizados en el archivo binario, estos corresponden a tipos enteros sin signo definidos en la biblioteca estándar de C1:
- uint32_t: Identificación de estación y timestamp.
- uint16_t: Presión y precipitaciones.
- int16_t: Temperatura.
- uint8_t: Humedad relativa.
Los valores almacenados multiplicados por 10 requieren reescalado posterior para recuperar la parte decimal.
Se utilizan exclusivamente librerías estándar:
- stdlib.h y stdio.h para gestión de memoria y entrada/salida.
- string.h para manipulación de cadenas.
- stdbool.h para uso de variables booleanas.
- time.h2 para manejo y conversión de tiempo.
- unistd.h y limits.h para obtener el directorio actual mediante
getcwd().
El programa implementa:
- Estructura
estacion_metalineada con el layout binario. - Validación de argumentos.
- Construcción dinámica de rutas.
- Apertura controlada de archivos.
- Procesamiento iterativo mediante
fread. - Conversión numérica y temporal.
- Escritura formateada con
fprintf.
El procesamiento central se basa en:
fread(&estacion, sizeof(estacion_met), 1, bin);Esto permite cumplir la restricción de memoria leyendo una única estación por iteración.
El timestamp almacenado representa segundos desde 01/01/2000.
Se convierte a época UNIX mediante:
__time_t tiempo_rel_UNIX = estacion.time + SEGUNDOS_2000_A_UNIX;
struct tm *tiempo = localtime(&tiempo_rel_UNIX);La función localtime()3 convierte segundos desde la época UNIX4 en una estructura tm con componentes de fecha y hora locales.
gcc main.c -o conversor
Modo simple:
.\conversor datos.bin salida
Modo con cambio de directorio:
.\conversor -cd /ruta/datos/ datos.bin salida
Si no se especifica nombre de destino, se utiliza estaciones_met.csv por defecto.
flowchart TD
A[Llamada al programa] --> B{¿Se especificó '-cd'?}
B -- Sí --> C[Nuevo directorio]
B -- No --> D{¿Hay argumentos?}
D -- No --> E[Error y finalizar]
D -- Sí --> F[Asignar archivo_bin]
C --> G[Construir ruta completa]
F --> H[Abrir archivos]
G --> H
H --> I[Escribir header CSV]
I --> J{fread retorna 1?}
J -- Sí --> K[Convertir datos]
K --> L[Escribir en CSV]
L --> J
J -- No --> M[Cerrar archivos]
M --> N[Informar directorio destino]