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.
}

Entradas relacionadas: