Menipulación de Archivos en C
En el lenguaje C, las operaciones de entrada y salida de archivos se gestionan mediante punteros a la estructura FILE, la cual está definida en la biblioteca estándar <stdio.h>. El manejo requiere una gestión explícita de la memoria y el estado del archivo.
Operaciones Básicas de Lectura y Escritura
Las funciones fopen, fputs, fgets y fclose constituyen la base para la transferencia de datos de texto.
#include <stdio.h>
void operaciones_basicas_c() {
const char* ruta_archivo = "datos.txt";
FILE* puntero_archivo = NULL;
char buffer_lectura[256];
// Escritura de datos
puntero_archivo = fopen(ruta_archivo, "w");
if (puntero_archivo != NULL) {
fputs("Contenido de ejemplo para el archivo de texto.\n", puntero_archivo);
fclose(puntero_archivo);
}
// Lectura de datos
puntero_archivo = fopen(ruta_archivo, "r");
if (puntero_archivo != NULL) {
if (fgets(buffer_lectura, sizeof(buffer_lectura), puntero_archivo) != NULL) {
printf("Datos leídos: %s", buffer_lectura);
}
fclose(puntero_archivo);
}
}
Funciones Avanzadas de Posicionamiento y Estado
Para un control más granular sobre el flujo de bytes, C proporciona rutinas para manipular el indicador de posición del archivo y verificar su estado interno.
#include <stdio.h>
void manipulacion_avanzada_c() {
FILE* flujo = fopen("registro.txt", "r+");
if (flujo == NULL) {
printf("Error crítico al abrir el archivo.\n");
return;
}
// Lectura de un solo carácter
int caracter = fgetc(flujo);
printf("Primer carácter leído: %c\n", (char)caracter);
// Rebobinar el flujo al inicio del archivo
rewind(flujo);
// Desplazar el indicador de posición: 5 bytes desde el inicio (SEEK_SET)
fseek(flujo, 5, SEEK_SET);
// Obtener la posición actual en bytes
long posicion_actual = ftell(flujo);
printf("Posición actual del puntero: %ld\n", posicion_actual);
// Verificar si se ha alcanzado el final del archivo
fseek(flujo, 0, SEEK_END);
fgetc(flujo); // Forzar lectura para activar el indicador EOF
if (feof(flujo)) {
printf("Se ha alcanzado el final del archivo (EOF).\n");
}
fclose(flujo);
}
Gestión de Archivos en C++
C++ abstrae las operaciones de archivos mediante flujos de datos (streams) orientados a objetos, definidos en la cabecera <fstream>. El ciclo de vida estándar implica instanciar el objeto de flujo, abrir el recurso, realizar las transferencias de datos y cerrar el flujo explícita o implícitamente.
Clases de Flujo y Modos de Apertura
La biblioteca estándar propocriona tres clases principales para interactuar con el sistema de archivos:
std::ifstream: Diseñado exclusivamente para operaciones de lectura (entrada).std::ofstream: Utilizado para operaciones de escritura (salida).std::fstream: Permite operaciones de lectura y escritura simultáneas.
Los modos de apertura permiten configurar el comportamiento del flujo:
std::ios::in: Abre para lectura.std::ios::out: Abre para escritura. Trunca el contenido existente por defecto.std::ios::app: Todas las operaciones de escritura se realizan al final del archivo.std::ios::ate: Abre el archivo y sitúa el indicador de posición al final inmediatamente.std::ios::binary: Abre el archivo en modo binario, evitando transformaciones de caracteres de nueva línea.
Implementación de Flujos en C++
El uso de los operadores de inserción (<<) y extracción (>>) simplifica drásticamente el formateo de datos en comparación con las funciones de C.
#include <iostream>
#include <fstream>
#include <string>
void operaciones_flujo_cpp() {
const std::string ruta = "registro.dat";
// Configuración del flujo de salida
std::ofstream escritor(ruta, std::ios::out | std::ios::trunc);
if (escritor.is_open()) {
escritor << "Identificador: 1024\n";
escritor << 3.14159 << "\n";
escritor.close();
}
// Configuración del flujo de entrada
std::ifstream lector(ruta, std::ios::in);
if (lector.is_open()) {
std::string linea_texto;
int id_valor;
double pi_valor;
// Lectura formateada basada en tipos de datos
lector >> id_valor >> pi_valor;
std::cout << "ID: " << id_valor << ", Pi: " << pi_valor << "\n";
// Lectura línea por línea ignorando espacios en blanco iniciales
while (std::getline(lector, linea_texto)) {
std::cout << "Línea procesada: " << linea_texto << "\n";
}
lector.close();
}
}