Gestión de Datos de Estrellas en C con Listas Enlazadas Dinámicas
Clasificado en Informática
Escrito el en español con un tamaño de 13,94 KB
Introducción
Este documento presenta la implementación en C de un sistema de gestión de datos para estrellas, utilizando una lista enlazada dinámica. El programa permite realizar operaciones CRUD (Crear, Leer, Actualizar, Borrar) sobre los registros de estrellas, así como guardar y recuperar los datos en un archivo binario.
Inclusión de Librerías y Definiciones
#include <stdio.h> // Para funciones de entrada/salida estándar (printf, scanf, fopen, fclose, fread, fwrite)
#include <stdlib.h> // Para funciones de utilidad general (malloc, free, system)
#include <string.h> // Para funciones de manipulación de cadenas (strcmp, gets)
#define MAXIMO_NOMBRE 50 // Define la longitud máxima para los campos de nombre y galaxia
Estructura de Datos para Estrellas
Se define una estructura para almacenar la información de cada estrella. Esta estructura contiene campos para el nombre, la galaxia, el número de planetas y la posibilidad de vida.
struct T_estrella {
char nombre[MAXIMO_NOMBRE];
char galaxia[MAXIMO_NOMBRE];
int planetas;
int vida; // 1 = Sí, 0 = No
};
Estructura de Nodo para la Lista Enlazada
Para construir la lista enlazada, se define una estructura de nodo que contendrá los datos de una estrella y un puntero al siguiente nodo en la secuencia.
struct Nodo {
struct T_estrella datos; // Almacena los datos de la estrella
struct Nodo *sig; // Puntero al siguiente nodo en la lista
};
Declaración de Punteros Globales
Se declaran punteros globales que gestionarán el inicio (cabecera) y el final (fin) de la lista enlazada, así como punteros auxiliares para operaciones.
struct Nodo *cabecera = NULL, *fin = NULL, *nuevo, *aux;
Prototipos de Funciones
A continuación, se listan los prototipos de las funciones que componen el programa, cada una encargada de una operación específica sobre la lista de estrellas.
int menu();
: Muestra el menú de opciones al usuario.void Mostrar_estrellas();
: Muestra todas las estrellas guardadas en la lista.void Insertar_estrellas();
: Permite añadir una nueva estrella a la lista.void Consulta_estrellas();
: Busca y muestra los datos de una estrella específica.void Modificacion_estrellas();
: Permite modificar los datos de una estrella existente.void Borrado_estrellas();
: Elimina una estrella de la lista.void Guardado_estrellas();
: Guarda la lista de estrellas en un archivo.void Recuperar_estrellas();
: Carga la lista de estrellas desde un archivo.void Salir();
: Finaliza la ejecución del programa.
Implementación de Funciones
Función Salir()
Esta función se encarga de mostrar un mensaje de salida y pausar la consola antes de finalizar el programa.
void Salir() {
printf("Saliendo del programa...\n");
system("pause");
}
Función Principal main()
La función main()
es el punto de entrada del programa. Gestiona el menú principal y la llamada a las diferentes funciones según la opción seleccionada por el usuario.
int main() {
int opcion;
do {
opcion = menu();
switch(opcion) {
case 1: Mostrar_estrellas();
break;
case 2: Insertar_estrellas();
break;
case 3: Consulta_estrellas();
break;
case 4: Modificacion_estrellas();
break;
case 5: Borrado_estrellas();
break;
case 6: Guardado_estrellas();
break;
case 7: Recuperar_estrellas();
break;
case 8: Salir();
break;
default:
printf("Opción no válida.\n");
}
} while (opcion != 8);
return 0;
}
Función Mostrar_estrellas()
Esta función recorre la lista enlazada y muestra los datos de cada estrella. Si la lista está vacía, informa al usuario.
void Mostrar_estrellas() {
system("cls");
if (cabecera == NULL) {
printf("No hay estrellas guardadas.\n");
} else {
aux = cabecera;
int i = 1;
while (aux != NULL) {
printf("Estrella #%d\n", i++);
printf("Nombre: %s\n", aux->datos.nombre);
printf("Galaxia: %s\n", aux->datos.galaxia);
printf("Número de planetas: %d\n", aux->datos.planetas);
printf("Posibilidad de vida: %s\n", aux->datos.vida ? "Sí" : "No");
aux = aux->sig;
}
}
system("pause");
}
Función Insertar_estrellas()
Permite al usuario introducir los datos de una nueva estrella y añadirla al final de la lista enlazada. Se realiza una asignación dinámica de memoria para el nuevo nodo.
void Insertar_estrellas() {
system("cls");
nuevo = (struct Nodo *)malloc(sizeof(struct Nodo));
if (nuevo == NULL) {
printf("Error al asignar memoria.\n");
return;
}
printf("Inserte el nombre de la estrella: ");
fflush(stdin);
gets(nuevo->datos.nombre);
printf("Inserte la galaxia a la que pertenece: ");
gets(nuevo->datos.galaxia);
printf("Inserte el número de planetas que la orbitan: ");
scanf("%d", &nuevo->datos.planetas);
printf("¿Existe la posibilidad de vida? (1 = Sí, 0 = No): ");
scanf("%d", &nuevo->datos.vida);
nuevo->sig = NULL;
if (cabecera == NULL) {
cabecera = nuevo;
fin = nuevo;
} else {
fin->sig = nuevo;
fin = nuevo;
}
printf("Estrella añadida con éxito.\n");
system("pause");
}
Función Consulta_estrellas()
Busca una estrella por su nombre en la lista enlazada y muestra sus datos si es encontrada.
void Consulta_estrellas() {
system("cls");
if (cabecera == NULL) {
printf("No hay estrellas en la lista.\n");
system("pause");
return;
}
char nombre[MAXIMO_NOMBRE];
printf("Introduce el nombre de la estrella a consultar: ");
fflush(stdin);
gets(nombre);
aux = cabecera;
while (aux != NULL && strcmp(aux->datos.nombre, nombre) != 0) {
aux = aux->sig;
}
if (aux != NULL) {
printf("Nombre: %s\n", aux->datos.nombre);
printf("Galaxia: %s\n", aux->datos.galaxia);
printf("Número de planetas: %d\n", aux->datos.planetas);
printf("Posibilidad de vida: %s\n", aux->datos.vida ? "Sí" : "No");
} else {
printf("Estrella no encontrada.\n");
}
system("pause");
}
Función Modificacion_estrellas()
Permite al usuario buscar una estrella por su nombre y luego modificar cualquiera de sus atributos.
void Modificacion_estrellas() {
system("cls");
if (cabecera == NULL) {
printf("No hay estrellas en la lista.\n");
system("pause");
return;
}
char nombre[MAXIMO_NOMBRE];
printf("Introduce el nombre de la estrella a modificar: ");
fflush(stdin);
gets(nombre);
aux = cabecera;
while (aux != NULL && strcmp(aux->datos.nombre, nombre) != 0) {
aux = aux->sig;
}
if (aux != NULL) {
int opcion;
do {
system("cls");
printf("Datos actuales de la estrella:\n");
printf("1. Nombre: %s\n", aux->datos.nombre);
printf("2. Galaxia: %s\n", aux->datos.galaxia);
printf("3. Número de planetas: %d\n", aux->datos.planetas);
printf("4. Posibilidad de vida: %s\n", aux->datos.vida ? "Sí" : "No");
printf("\nSeleccione el dato que desea modificar:\n");
printf("1. Nombre\n");
printf("2. Galaxia\n");
printf("3. Número de planetas\n");
printf("4. Posibilidad de vida\n");
printf("5. Salir de la modificación\n");
scanf("%d", &opcion);
switch (opcion) {
case 1:
printf("Introduce el nuevo nombre: ");
fflush(stdin);
gets(aux->datos.nombre);
printf("Nombre modificado con éxito.\n");
break;
case 2:
printf("Introduce la nueva galaxia: ");
fflush(stdin);
gets(aux->datos.galaxia);
printf("Galaxia modificada con éxito.\n");
break;
case 3:
printf("Introduce el nuevo número de planetas: ");
scanf("%d", &aux->datos.planetas);
printf("Número de planetas modificado con éxito.\n");
break;
case 4:
printf("¿Existe la posibilidad de vida? (1 = Sí, 0 = No): ");
scanf("%d", &aux->datos.vida);
printf("Posibilidad de vida modificada con éxito.\n");
break;
case 5:
printf("Saliendo del menú de modificación...\n");
break;
default:
printf("Opción no válida. Inténtelo de nuevo.\n");
}
system("pause");
} while (opcion != 5);
} else {
printf("Estrella no encontrada.\n");
}
system("pause");
}
Función Borrado_estrellas()
Esta función permite eliminar una estrella de la lista enlazada buscando por su nombre. Maneja casos de eliminación de la cabecera, el final o un nodo intermedio.
void Borrado_estrellas() {
system("cls");
if (cabecera == NULL) {
printf("No hay estrellas en la lista.\n");
system("pause");
return;
}
char nombre[MAXIMO_NOMBRE];
struct Nodo *anterior = NULL;
int encontrada = 0;
do {
printf("Introduce el nombre de la estrella a borrar: ");
fflush(stdin);
gets(nombre);
aux = cabecera;
anterior = NULL;
encontrada = 0;
// Recorrer la lista para buscar la estrella
while (aux != NULL) {
if (strcmp(aux->datos.nombre, nombre) == 0) {
encontrada = 1;
break;
}
anterior = aux;
aux = aux->sig;
}
if (!encontrada) {
printf("Estrella no encontrada. Inténtalo de nuevo.\n");
}
} while (!encontrada);
// Eliminar el nodo
if (anterior == NULL) { // Si es la primera estrella
cabecera = aux->sig;
} else {
anterior->sig = aux->sig;
}
if (aux == fin) {
fin = anterior; // Si es la última estrella
}
free(aux); // Liberar la memoria del nodo
printf("Estrella borrada con éxito.\n");
system("pause");
}
Función Guardado_estrellas()
Esta función guarda todos los datos de las estrellas de la lista enlazada en un archivo binario llamado estrellas.dat
.
void Guardado_estrellas() {
FILE *f = fopen("estrellas.dat", "wb");
if (f == NULL) {
printf("Error al abrir el archivo.\n");
return;
}
aux = cabecera;
while (aux != NULL) {
fwrite(&aux->datos, sizeof(struct T_estrella), 1, f);
aux = aux->sig;
}
fclose(f);
printf("Datos guardados con éxito.\n");
system("pause");
}
Función Recuperar_estrellas()
Esta función carga los datos de las estrellas desde el archivo binario estrellas.dat
y reconstruye la lista enlazada. Primero, limpia cualquier lista existente en memoria.
void Recuperar_estrellas() {
FILE *f = fopen("estrellas.dat", "rb");
if (f == NULL) {
printf("No se ha encontrado el archivo.\n");
return;
}
// Limpiar la lista actual
while (cabecera != NULL) {
aux = cabecera;
cabecera = cabecera->sig;
malloc(aux); // ERROR LÓGICO: Esto debería ser free(aux) para liberar la memoria.
// Se mantiene como en el original para no alterar el contenido.
}
struct T_estrella temp;
while (fread(&temp, sizeof(struct T_estrella), 1, f) == 1) {
nuevo = (struct Nodo *)malloc(sizeof(struct Nodo));
if (nuevo == NULL) {
printf("Error al asignar memoria.\n");
fclose(f);
return;
}
nuevo->datos = temp;
nuevo->sig = NULL;
if (cabecera == NULL) {
cabecera = nuevo;
fin = nuevo;
} else {
fin->sig = nuevo;
// Las siguientes líneas están mal indentadas y lógicamente fuera de lugar en el original.
// Se mantienen como en el original para no alterar el contenido.
fclose(f);
fin = nuevo;
printf("Datos recuperados con éxito.\n");
system("pause");
}
}
// Si el bucle termina sin entrar al 'else' (ej. solo un elemento),
// o si hay múltiples elementos, fclose, printf y system("pause") no se ejecutarán
// correctamente o se ejecutarán prematuramente debido a su ubicación original.
// Se mantiene como en el original para no alterar el contenido.
}