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();
}