Implementación de Pilas y Manejo de Archivos en C: Ejemplos Prácticos

Clasificado en Informática

Escrito el en español con un tamaño de 12,21 KB

Operaciones con Pilas en C: Crear y Visualizar

Ejemplo de código en C para crear una pila utilizando estructuras y punteros, insertar elementos (alumnos con nombre y edad) y luego mostrar el contenido de la pila.


#include <stdio.h>  // Añadido para printf, scanf, getchar, flushall, gets
#include <stdlib.h> // Añadido para new (C++) o malloc (C), delete (C++) o free (C)
// Nota: 'new' y 'delete' son operadores de C++, no de C estándar.
// Para C estándar, se usaría malloc y free.
// Nota: 'flushall' no es estándar C. Su comportamiento puede variar.

// Definición de la estructura para los nodos de la pila
struct datos {
    char nombre[15];
    int edad;
    struct datos *siguiente;
};

void main(void) {
    struct datos *pila = NULL, *nodo = NULL, *fuera = NULL;
    char respuesta;

    // Intenta reservar memoria para el primer nodo
    // En C++ sería: nodo = new datos;
    // En C estándar sería: nodo = (struct datos*)malloc(sizeof(struct datos));
    nodo = (struct datos*)malloc(sizeof(struct datos));

    if (nodo != NULL) {
        nodo->siguiente = NULL;
        pila = nodo;

        // Bucle para insertar elementos en la pila
        do {
            printf("\n\tIntroduce el nombre del alumno: ");
            // flushall(); // No estándar, alternativa comentada
            fflush(stdin); // No estándar y comportamiento indefinido en input, pero común en algunos compiladores
            // gets(nodo->nombre); // Inseguro, usar fgets en su lugar
            fgets(nodo->nombre, 15, stdin); 
            // Eliminar el salto de línea que fgets puede dejar
            nodo->nombre[strcspn(nodo->nombre, "\n")] = 0;

            printf("\n\tIntroduce la edad del alumno: ");
            scanf("%d", &nodo->edad);
            // Limpiar buffer después de scanf
            while (getchar() != '\n'); 

            printf("\n\n\t¿Desea continuar metiendo alumnos? (s/n): ");
            // flushall(); // No estándar
            fflush(stdin); // No estándar
            respuesta = getchar();
            // Limpiar buffer después de getchar
            while (getchar() != '\n'); 

            if (respuesta == 's' || respuesta == 'S') {
                // Reservar memoria para el nuevo nodo
                // En C++: nodo = new datos;
                // En C: nodo = (struct datos*)malloc(sizeof(struct datos));
                struct datos *nuevo_nodo = (struct datos*)malloc(sizeof(struct datos));
                if (nuevo_nodo != NULL) {
                    nuevo_nodo->siguiente = pila;
                    pila = nuevo_nodo;
                    nodo = nuevo_nodo; // El nuevo nodo es ahora el actual para rellenar datos
                } else {
                    printf("\n\n\tError: No se pudo reservar memoria para nuevo nodo.");
                    respuesta = 'n'; // Salir del bucle si no hay memoria
                }
            }
        } while (respuesta == 's' || respuesta == 'S');

        // Visualizar la pila (desde la cima)
        printf("\n\n--- Contenido de la Pila ---");
        nodo = pila;
        while (nodo != NULL) {
            // Solo mostrar si el nodo actual no es el nodo 'fantasma' inicial (si se usó esa lógica)
            // o si se rellenaron sus datos. Asumiendo que todos los nodos en la pila tienen datos válidos.
            if (nodo->nombre[0] != '\0') { // Comprobar si el nombre no está vacío como indicador
                 printf("\n\tNombre: %s", nodo->nombre);
                 printf("\n\tEdad: %d", nodo->edad);
            }
            nodo = nodo->siguiente;
        }
        printf("\n--------------------------\n");

        

Extraer Nodos y Comprobar Estado de la Pila

printf("\n--- Extrayendo Nodos de la Pila ---"); nodo = pila; // Empezamos desde la cima para extraer // Corrección: El bucle original tenía una sintaxis incorrecta y lógica confusa. // Este bucle extraerá y mostrará cada nodo hasta vaciar la pila. while (pila != NULL) { // Mientras la pila no esté vacía printf("\n\n\tEXTRAYENDO NODO:"); fuera = pila; // Nodo a extraer es la cima actual pila = pila->siguiente; // Mover la cima al siguiente nodo// Mostrar nodo extraído printf("\n\t Nombre extraído: %s", fuera->nombre); printf("\n\t Edad extraída: %d", fuera->edad); // Liberar memoria del nodo extraído // En C++: delete fuera; // En C: free(fuera); free(fuera); fuera = NULL;// Mostrar estado actual de la pila printf("\n\n\t ESTADO ACTUAL DE LA PILA:"); nodo = pila; if (nodo == NULL) { printf("\n\t Pila vacía."); } else { while (nodo != NULL) { printf("\n\t Nombre: %s", nodo->nombre); printf("\n\t Edad: %d", nodo->edad); nodo = nodo->siguiente; } } printf("\n--------------------------"); } printf("\n--- Pila Vaciada ---\n");// Liberar memoria restante (si la lógica anterior fallara, aunque no debería) // El bucle de extracción ya debería haber vaciado y liberado todo. /* nodo = pila; while (nodo != NULL) { struct datos *temp = nodo; nodo = nodo->siguiente; free(temp); } pila = NULL; */} else { printf("\n\n\tError: No se ha podido reservar memoria inicial."); }printf("\n\n\tPulsa una tecla para salir..."); // flushall(); // No estándar fflush(stdin); // No estándar getchar(); }

Manejo de Archivos en C: Crear, Visualizar y Buscar Registros

Ejemplos de código en C para trabajar con archivos binarios, incluyendo la creación de un archivo, escritura de registros (datos de alumnos), lectura y visualización del contenido, y búsqueda de registros específicos.


#include <stdio.h>  // Para funciones de E/S (printf, scanf, fopen, fwrite, fread, fclose, etc.)
#include <stdlib.h> // Para exit (si fuera necesario), malloc/free (no usado aquí directamente)
#include <string.h> // Para strcmp
#include <ctype.h>  // Para tolower
// #include <conio.h> // Para clrscr, getch (no estándar, dependen del compilador/SO)

// Definición de la estructura para los registros de alumnos
struct registro {
    int matricula;
    char nombre[30];
    char sexo;
    int edad;
    int nota;
};

// Prototipos de funciones (si se modulariza)
// void crearYVisualizarArchivo();
// void buscarEnArchivo();

void main(void) {
    struct registro alumno;
    FILE *archivo;
    char opcion;
    int i = 1;
    char busqueda[30];
    int buscar;
    int encontrado = 0;
    int resultado;

    

Creación y Visualización del Archivo

// Abrir archivo para lectura y escritura binaria (crea si no existe) archivo = fopen("matriculas.txt", "wb+"); // Usar wb+ para asegurar creación y permitir lectura/escrituraif (archivo == NULL) { printf("Error: No ha sido posible abrir/crear matriculas.txt\n"); return; // Salir si no se puede abrir el archivo } else { printf("Archivo 'matriculas.txt' abierto/creado correctamente.\n");// Bucle para introducir datos de alumnos do { // flushall(); // No estándar fflush(stdin); // No estándaralumno.matricula = i; printf("\n\n Introduzca el nombre del alumno %d: ", i); // gets(alumno.nombre); // Inseguro fgets(alumno.nombre, 30, stdin); alumno.nombre[strcspn(alumno.nombre, "\n")] = 0; // Eliminar salto de líneaprintf("\n Introduzca el sexo del alumno (M/F): "); alumno.sexo = tolower(getchar()); while (getchar() != '\n'); // Limpiar bufferprintf("\n Introduzca la edad del alumno: "); scanf("%d", &alumno.edad); while (getchar() != '\n'); // Limpiar bufferprintf("\n Introduzca la nota del alumno: "); scanf("%d", &alumno.nota); while (getchar() != '\n'); // Limpiar buffer// Escribir el registro en el archivo fwrite(&alumno, sizeof(struct registro), 1, archivo);i++; printf("\n\n ¿Desea introducir otro alumno? (s/n): "); // flushall(); // No estándar fflush(stdin); // No estándar opcion = tolower(getchar()); while (getchar() != '\n'); // Limpiar buffer} while (opcion == 's');printf("\n\n El fichero se ha poblado satisfactoriamente.\n");// Visualizar los datos introducidos printf("\n\n--- Datos introducidos en el fichero ---"); rewind(archivo); // Volver al inicio del archivo para leerwhile (fread(&alumno, sizeof(struct registro), 1, archivo) == 1) { printf("\n Matrícula: %d", alumno.matricula); printf("\n Nombre: %s", alumno.nombre); printf("\n Sexo: %c", alumno.sexo); printf("\n Edad: %d", alumno.edad); printf("\n Nota: %d\n", alumno.nota); } printf("-------------------------------------\n");// No cerrar el archivo aquí si se va a usar en la búsqueda // fclose(archivo); }

Búsqueda de Alumnos en el Archivo

// Asegurarse de que el archivo está abierto (ya debería estarlo desde la sección anterior) if (archivo == NULL) { printf("\nError: El archivo no está disponible para búsqueda.\n"); return; }do { // clrscr(); // No estándar, limpiar pantalla printf("\n\n ####### BÚSQUEDA DE ALUMNOS #######\n"); printf(" -----------------------------------------\n"); printf("\n 1.- BÚSQUEDA POR NOMBRE"); printf("\n 2.- BÚSQUEDA POR MATRÍCULA"); printf("\n 3.- SALIR"); printf("\n -----------------------------------------\n"); printf("\n\n Elija una de las opciones de búsqueda: "); // flushall(); // No estándar fflush(stdin); // No estándar opcion = getchar(); while (getchar() != '\n'); // Limpiar bufferswitch (opcion) { case '1': // flushall(); // No estándar fflush(stdin); // No estándar encontrado = 0;printf("\n\n Introduzca el nombre del alumno a buscar: "); // gets(busqueda); // Inseguro fgets(busqueda, 30, stdin); busqueda[strcspn(busqueda, "\n")] = 0; // Eliminar salto de línearewind(archivo); // Volver al inicio para buscar desde el principio printf("\n MATRÍCULA NOMBRE SEXO EDAD NOTA\n"); printf(" ----------------------------------------------------\n"); // Leer secuencialmente y comparar while (fread(&alumno, sizeof(struct registro), 1, archivo) == 1) { resultado = strcmp(alumno.nombre, busqueda); if (resultado == 0) { printf(" %-11d %-17s %-7c %-7d %-4d\n", alumno.matricula, alumno.nombre, alumno.sexo, alumno.edad, alumno.nota); encontrado = 1; // Podríamos añadir 'break;' si solo esperamos un resultado } }if (encontrado == 0) { printf("\n\n Su alumno no existe.\n"); } break;case '2': // flushall(); // No estándar fflush(stdin); // No estándar encontrado = 0; printf("\n\n Introduzca el número de matrícula que quiera buscar: "); scanf("%d", &buscar); while (getchar() != '\n'); // Limpiar bufferprintf("\n MATRÍCULA NOMBRE SEXO EDAD NOTA\n"); printf(" ----------------------------------------------------\n"); // Intentar búsqueda directa por posición (asumiendo matrícula = posición - 1) // ¡PRECAUCIÓN! Esto solo funciona si las matrículas son 1, 2, 3... y no hay huecos. long posicion = (long)(buscar - 1) * sizeof(struct registro); if (fseek(archivo, posicion, SEEK_SET) == 0) { // fseek exitoso, intentar leer if (fread(&alumno, sizeof(struct registro), 1, archivo) == 1) { // Comprobar si la matrícula leída coincide (por si hubo huecos o desorden) if (alumno.matricula == buscar) { printf(" %-11d %-17s %-7c %-7d %-4d\n", alumno.matricula, alumno.nombre, alumno.sexo, alumno.edad, alumno.nota); encontrado = 1; } } } // Si fseek falló o no se encontró, buscar secuencialmente como respaldo if (!encontrado) { rewind(archivo); while (fread(&alumno, sizeof(struct registro), 1, archivo) == 1) { if (alumno.matricula == buscar) { printf(" %-11d %-17s %-7c %-7d %-4d\n", alumno.matricula, alumno.nombre, alumno.sexo, alumno.edad, alumno.nota); encontrado = 1; break; // Encontrado, salir del bucle while } } }if (encontrado == 0) { printf("\n\n Su alumno no existe o la matrícula no es válida.\n"); } break;case '3': printf("\n Saliendo del menú de búsqueda...\n"); break;default: printf("\n Opción no válida. Intente de nuevo.\n"); break; }if (opcion != '3') { printf("\n\n Pulse una tecla para volver al menú..."); // flushall(); // No estándar fflush(stdin); // No estándar getchar(); }} while (opcion != '3');// Cerrar el archivo al final de todas las operaciones if (archivo != NULL) { fclose(archivo); printf("\n\n Archivo 'matriculas.txt' cerrado correctamente.\n"); }printf("\n Pulse una tecla para salir del programa..."); // flushall(); // No estándar fflush(stdin); // No estándar getchar(); }

Entradas relacionadas: