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
