Guardar y recuperar colección de struct en archivo usando C++

Guardar y recuperar struct en archivo usando C++

En el post de hoy veremos cómo guardar los datos de un vector de struct en un archivo de texto para más tarde poder recuperarlo.

Es decir, guardar varias estructuras (un arreglo de ellas) en un archivo y en cualquier otro momento del tiempo leer ese archivo y convertirlo de nuevo a una colección de structs usando C++.

Básicamente vamos a serializar y deserializar structs en un archivo usando CPP.

Explicación general

Para poder guardar un struct en un archivo simplemente debemos guardar todas sus propiedades, y separarlas de alguna manera. Al momento de recuperarlas debemos hacer el proceso inverso.

Entonces lo único que hace falta es escribir todas las propiedades separadas por un delimitador, y luego separar cada struct con algo como un salto de línea.

Al momento de leer el archivo y convertirlo a la colección de structs separamos la línea leída usando el delimitador, y vamos asignando las propiedades.

No olvides que todo debe ser exactamente en el mismo orden.

Estructura de ejemplo

Aquí tengo un ejemplo de un struct que usé para otro post. Lo que haremos será guardar una colección de estructuras en un archivo.

Comenzamos declarando la estructura y unas constantes útiles:

const string NOMBRE_ARCHIVO = "personas.txt";
const char DELIMITADOR = ',';

struct Persona
{
	int edad;
	string nombre;
};

Guardar struct en un archivo

Veamos la siguiente parte que sería escribir una función que abra el archivo, recorra el vector de struct y escriba cada propiedad:

void guardar_personas_en_archivo(vector<Persona> personas)
{
	ofstream archivo;
	archivo.open(NOMBRE_ARCHIVO, fstream::out);
	int i;
	for (i = 0; i < personas.size(); i++)
	{
		Persona persona = personas[i];
		archivo << persona.edad << DELIMITADOR << persona.nombre << "\n";
	}
	archivo.close();
}

Tenemos la función. Abrimos el archivo en la línea 4, recorremos la colección de estructuras en la línea 6, luego accedemos al struct actual en la línea 8 y escribimos el contenido en el archivo en la línea 9.

Fíjate en que estamos escribiendo primero la edad, luego el delimitador, más tarde el nombre y finalmente un salto de línea.

Cuando la función se acabe de ejecutar vamos a tener todos los structs guardados en un archivo.

Nota: recuerda que esto va a sobrescribir el contenido del archivo. Si tú quieres, puedes adjuntar el contenido con la opción append.

Recuperar struct de archivo en C++

Ahora veamos el proceso inverso: leer la colección de estructuras de un archivo y convertirlas de nuevo a un vector. El código queda así:

vector<Persona> obtener_personas_de_archivo()
{
	vector<Persona> personas;
	Persona persona;
	ifstream archivo(NOMBRE_ARCHIVO.c_str());
	string linea, edad, nombre;
	while (getline(archivo, linea))
	{
		stringstream input_stringstream(linea);
		getline(input_stringstream, edad, DELIMITADOR);
		getline(input_stringstream, nombre, DELIMITADOR);
		persona.edad = stoi(edad); // Edad es cadena. Asignamos la propiedad según lo que regrese "stoi"
		persona.nombre = nombre;
		personas.push_back(persona);
	}
	return personas;
}

Abrimos el archivo en la línea 5, luego leemos del archivo mientras haya líneas en la línea 7.

Ya dentro del ciclo while creamos un input_stringstream para separar la cadena usando el delimitador y obtenemos primero la edad y luego el nombre, ambos como cadenas.

Luego en la línea 12 convertimos la edad a entero y la asignamos al struct, al igual que la línea 13 en donde asignamos el nombre pero no hacemos conversión porque ya es una cadena.

Finalmente en la línea 14 agregamos el struct al vector y cuando el ciclo se acaba (es decir, que ya no hay líneas para leer) regresamos el vector.

Poniendo todo junto

Ahora veamos esas funciones de C++ ejecutándose. También he agregado una función adicional para imprimir el vector. El código completo queda así:

// https://parzibyte.me/blog
#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>

using namespace std;

const string NOMBRE_ARCHIVO = "personas.txt";
const char DELIMITADOR = ',';

struct Persona
{
	int edad;
	string nombre;
};

vector<Persona> obtener_personas_de_archivo()
{
	vector<Persona> personas;
	Persona persona;
	ifstream archivo(NOMBRE_ARCHIVO.c_str());
	string linea, edad, nombre;
	while (getline(archivo, linea))
	{
		stringstream input_stringstream(linea);
		getline(input_stringstream, edad, DELIMITADOR);
		getline(input_stringstream, nombre, DELIMITADOR);
		persona.edad = stoi(edad); // Edad es cadena. Asignamos la propiedad según lo que regrese "stoi"
		persona.nombre = nombre;
		personas.push_back(persona);
	}
	return personas;
}

void guardar_personas_en_archivo(vector<Persona> personas)
{
	ofstream archivo;
	archivo.open(NOMBRE_ARCHIVO, fstream::out);
	int i;
	for (i = 0; i < personas.size(); i++)
	{
		Persona persona = personas[i];
		archivo << persona.edad << DELIMITADOR << persona.nombre << "\n";
	}
	archivo.close();
}

void imprimir_personas(vector<Persona> personas)
{

	int i;
	for (i = 0; i < personas.size(); i++)
	{
		Persona persona = personas.at(i);
		cout << "Tenemos a la persona " << persona.nombre << " con edad " << persona.edad << "\n";
	}
}

int main(int argc, char const *argv[])
{
	vector<Persona> personasParaGuardar;
	personasParaGuardar.push_back(Persona{20, "Luis"});
	personasParaGuardar.push_back(Persona{40, "Leon"});
	personasParaGuardar.push_back(Persona{15, "Marijo"});
	personasParaGuardar.push_back(Persona{90, "Chris"});
	guardar_personas_en_archivo(personasParaGuardar);
	// Obtenerlas de nuevo
	vector<Persona> personasLeidasDeArchivo = obtener_personas_de_archivo();
	imprimir_personas(personasLeidasDeArchivo);
	return 0;
}

El modo de uso está indicado en la función main. Obviamente el llenado del vector puede venir de cualquier lugar; yo simplemente lo he llenado manualmente para luego escribirlo en el archivo en la línea 67, y recuperarlo en la 69.

Al ejecutarlo tenemos la siguiente salida, que coincide con el contenido del archivo:

Guardar y recuperar colección de struct en archivo usando C++
Guardar y recuperar colección de struct en archivo usando C++

Y ya con esto puedes trabajar con estructuras más complejas, ya sea que cambies las propiedades, los delimitadores o cualquier otra cosa.

Para terminar te dejo con más tutoriales de C++.

Estoy aquí para ayudarte 🤝💻


Estoy aquí para ayudarte en todo lo que necesites. Si requieres alguna modificación en lo presentado en este post, deseas asistencia con tu tarea, proyecto o precisas desarrollar un software a medida, no dudes en contactarme. Estoy comprometido a brindarte el apoyo necesario para que logres tus objetivos. Mi correo es parzibyte(arroba)gmail.com, estoy como@parzibyte en Telegram o en mi página de contacto

No te pierdas ninguno de mis posts 🚀🔔

Suscríbete a mi canal de Telegram para recibir una notificación cuando escriba un nuevo tutorial de programación.

2 comentarios en “Guardar y recuperar struct en archivo usando C++”

Dejar un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *