En esta sección, vamos a poner en práctica todo lo que hemos aprendido a lo largo del curso mediante la implementación de un proyecto final. Este proyecto servirá como una evaluación integral de tus habilidades en programación en C y te permitirá consolidar tus conocimientos.
Objetivos del Proyecto
- Aplicar conceptos básicos y avanzados de C: Desde la sintaxis básica hasta el manejo de memoria dinámica y multihilo.
- Desarrollar un programa funcional: Crear un programa que resuelva un problema real o simulado.
- Practicar la depuración y optimización: Asegurarse de que el programa sea eficiente y libre de errores.
- Documentar el código: Escribir comentarios y documentación para que el código sea fácil de entender y mantener.
Descripción del Proyecto
Proyecto: Sistema de Gestión de Biblioteca
Desarrollar un sistema de gestión de biblioteca que permita a los usuarios realizar las siguientes operaciones:
- Agregar un nuevo libro: Ingresar detalles como título, autor, ISBN, y cantidad disponible.
- Eliminar un libro: Eliminar un libro del sistema utilizando su ISBN.
- Buscar un libro: Buscar un libro por título o autor.
- Listar todos los libros: Mostrar una lista de todos los libros disponibles en la biblioteca.
- Prestar un libro: Registrar el préstamo de un libro a un usuario.
- Devolver un libro: Registrar la devolución de un libro prestado.
Requisitos Técnicos
- Estructuras y Uniones: Utilizar estructuras para representar libros y usuarios.
- Punteros y Memoria Dinámica: Utilizar punteros para manejar listas dinámicas de libros y usuarios.
- Archivos: Guardar y cargar datos de libros y usuarios desde archivos.
- Funciones: Modularizar el código utilizando funciones para cada operación.
- Manejo de Errores: Implementar manejo de errores para entradas inválidas y operaciones fallidas.
Estructura del Código
- Definición de Estructuras
#include <stdio.h> #include <stdlib.h> #include <string.h> // Estructura para representar un libro typedef struct { char title[100]; char author[100]; char ISBN[13]; int quantity; } Book; // Estructura para representar un usuario typedef struct { char name[100]; char borrowedISBN[13]; } User;
- Funciones para Manejo de Libros
Agregar un Nuevo Libro
void addBook(Book **books, int *count) { Book newBook; printf("Ingrese el título del libro: "); scanf("%s", newBook.title); printf("Ingrese el autor del libro: "); scanf("%s", newBook.author); printf("Ingrese el ISBN del libro: "); scanf("%s", newBook.ISBN); printf("Ingrese la cantidad disponible: "); scanf("%d", &newBook.quantity); books[*count] = (Book *)malloc(sizeof(Book)); if (books[*count] == NULL) { printf("Error al asignar memoria.\n"); return; } *books[*count] = newBook; (*count)++; }
Eliminar un Libro
void deleteBook(Book **books, int *count, const char *ISBN) { for (int i = 0; i < *count; i++) { if (strcmp(books[i]->ISBN, ISBN) == 0) { free(books[i]); for (int j = i; j < *count - 1; j++) { books[j] = books[j + 1]; } (*count)--; printf("Libro eliminado exitosamente.\n"); return; } } printf("Libro no encontrado.\n"); }
Buscar un Libro
void searchBook(Book **books, int count, const char *query) { for (int i = 0; i < count; i++) { if (strstr(books[i]->title, query) != NULL || strstr(books[i]->author, query) != NULL) { printf("Título: %s, Autor: %s, ISBN: %s, Cantidad: %d\n", books[i]->title, books[i]->author, books[i]->ISBN, books[i]->quantity); } } }
Listar Todos los Libros
void listBooks(Book **books, int count) { for (int i = 0; i < count; i++) { printf("Título: %s, Autor: %s, ISBN: %s, Cantidad: %d\n", books[i]->title, books[i]->author, books[i]->ISBN, books[i]->quantity); } }
- Funciones para Manejo de Préstamos
Prestar un Libro
void borrowBook(Book **books, int count, User *user) { printf("Ingrese el ISBN del libro a prestar: "); scanf("%s", user->borrowedISBN); for (int i = 0; i < count; i++) { if (strcmp(books[i]->ISBN, user->borrowedISBN) == 0 && books[i]->quantity > 0) { books[i]->quantity--; printf("Libro prestado exitosamente.\n"); return; } } printf("Libro no disponible.\n"); }
Devolver un Libro
void returnBook(Book **books, int count, User *user) { for (int i = 0; i < count; i++) { if (strcmp(books[i]->ISBN, user->borrowedISBN) == 0) { books[i]->quantity++; printf("Libro devuelto exitosamente.\n"); return; } } printf("Error al devolver el libro.\n"); }
- Funciones para Manejo de Archivos
Guardar Datos en Archivos
void saveData(Book **books, int count) { FILE *file = fopen("books.dat", "wb"); if (file == NULL) { printf("Error al abrir el archivo.\n"); return; } fwrite(&count, sizeof(int), 1, file); for (int i = 0; i < count; i++) { fwrite(books[i], sizeof(Book), 1, file); } fclose(file); }
Cargar Datos desde Archivos
void loadData(Book **books, int *count) { FILE *file = fopen("books.dat", "rb"); if (file == NULL) { printf("Error al abrir el archivo.\n"); return; } fread(count, sizeof(int), 1, file); for (int i = 0; i < *count; i++) { books[i] = (Book *)malloc(sizeof(Book)); if (books[i] == NULL) { printf("Error al asignar memoria.\n"); return; } fread(books[i], sizeof(Book), 1, file); } fclose(file); }
- Función Principal
int main() { Book *books[100]; int bookCount = 0; User user; int choice; loadData(books, &bookCount); while (1) { printf("1. Agregar Libro\n2. Eliminar Libro\n3. Buscar Libro\n4. Listar Libros\n5. Prestar Libro\n6. Devolver Libro\n7. Guardar y Salir\n"); printf("Ingrese su elección: "); scanf("%d", &choice); switch (choice) { case 1: addBook(books, &bookCount); break; case 2: char ISBN[13]; printf("Ingrese el ISBN del libro a eliminar: "); scanf("%s", ISBN); deleteBook(books, &bookCount, ISBN); break; case 3: char query[100]; printf("Ingrese el título o autor del libro a buscar: "); scanf("%s", query); searchBook(books, bookCount, query); break; case 4: listBooks(books, bookCount); break; case 5: printf("Ingrese su nombre: "); scanf("%s", user.name); borrowBook(books, bookCount, &user); break; case 6: returnBook(books, bookCount, &user); break; case 7: saveData(books, bookCount); for (int i = 0; i < bookCount; i++) { free(books[i]); } exit(0); default: printf("Opción inválida.\n"); } } return 0; }
Ejercicios Prácticos
- Agregar Funcionalidad de Usuarios: Extiende el sistema para manejar múltiples usuarios y sus préstamos.
- Mejorar la Interfaz de Usuario: Implementa un menú más amigable y opciones de entrada más robustas.
- Optimizar el Código: Revisa y optimiza el código para mejorar el rendimiento y reducir el uso de memoria.
Conclusión
La implementación de este proyecto te permitirá aplicar una amplia gama de conceptos de programación en C, desde estructuras y punteros hasta manejo de archivos y memoria dinámica. Asegúrate de seguir buenas prácticas de codificación y documentar tu código adecuadamente. ¡Buena suerte!
Curso de Programación en C
Módulo 1: Introducción a C
- Introducción a la Programación
- Configuración del Entorno de Desarrollo
- Programa Hola Mundo
- Sintaxis y Estructura Básica
Módulo 2: Tipos de Datos y Variables
Módulo 3: Flujo de Control
Módulo 4: Funciones
- Introducción a las Funciones
- Argumentos de Función y Valores de Retorno
- Ámbito y Vida de las Variables
- Funciones Recursivas
Módulo 5: Arreglos y Cadenas
- Introducción a los Arreglos
- Arreglos Multidimensionales
- Manejo de Cadenas
- Funciones de Arreglos y Cadenas
Módulo 6: Punteros
Módulo 7: Estructuras y Uniones
Módulo 8: Asignación Dinámica de Memoria
Módulo 9: Manejo de Archivos
- Introducción al Manejo de Archivos
- Lectura y Escritura de Archivos
- Posicionamiento de Archivos
- Manejo de Errores en Operaciones de Archivos
Módulo 10: Temas Avanzados
- Directivas del Preprocesador
- Argumentos de Línea de Comandos
- Listas de Argumentos Variables
- Multihilo en C
Módulo 11: Mejores Prácticas y Optimización
- Legibilidad del Código y Documentación
- Técnicas de Depuración
- Optimización del Rendimiento
- Consideraciones de Seguridad