Biblioteca: Soluci贸n comentada¶
Pasos previos¶
- Mejores pr谩cticas: revisar Dec谩logo 馃槑馃槑
- An谩lisis concienzudo del las definiciones de los tipos de datos
- Esqueleto de c贸digo conforme a la definici贸n de tareas y el API del programa
Esqueleto del programa#include <stdlib.h> #include <string.h> #include "biblio.h" /* * Variable local para la biblioteca */ tipoBiblio biblio; /* * C贸digo equivalente a la declaraci贸n est谩tica de * un libro pero utilizando memoria din谩mica * Declaraci贸n est谩tica: Libro miLibro; */ ptrLibro newLibro(int isbn, char *titulo, char *autor, char *descripcion) { return NULL; } /* * getter Libro. Devuelve su direcci贸n en la biblioteca */ ptrLibro getLibro(int n) { return NULL; } /* * A帽ade libro a la biblioteca * Devuelve 0 si hay espacio y 1 en caso contrario */ int putLibro(ptrLibro p) { return -1; } /* * Crea una biblioteca para n libros * Si modo es 0 define un array de n punteros a Libro * y si es 1 utiliza un array de libros * Devuelve 0 si se crea y 1 en caso contrario */ int newBiblio(unsigned char modo, int n) { return -1; } /* * Libera la memoria (din谩mica) asociada con la biblioteca * Seg煤n el modo libera memoria del array de libros * o del array de punteros a libros */ void freeBiblio(void) { } /* * Ampl铆a la biblioteca para acomodar n libros m谩s * Devuelve 0 si se ampl铆a y 1 en caso contrario */ int masBiblio(int n) { return -1; } - 脫rdenes de compilaci贸n gcc
# Compilar gcc -Wall -Wextra -pedantic -Werror -ansi -c biblio.c -o bin/biblio.o gcc -Wall -Wextra -pedantic -Werror -ansi -c ejemplo.c -o bin/ejemplo.o # Montar gcc bin/ejemplo.o bin/biblio.o -o bin/biblio
Implementaci贸n de biblio.c¶
Crear biblioteca (sin libros): int newBiblio(unsigned char modo, int n)¶
/*
* Crea una biblioteca para n libros
* Si modo es 0 define un array de n punteros a Libro
* y si es 1 utiliza un array de libros
* Devuelve 0 si se crea y 1 en caso contrario
*/
int newBiblio(unsigned char modo, int n) {
int rcode = 1;
/* biblio es local, se accede directamente a los campos del struct */
biblio.lmax = n;
biblio.lnum = 0;
biblio.modo = modo;
if(modo == '0') {
/*
* Definir array de n punteros a libros
*/
biblio.libptr = (ptrLibro *) calloc(n, (int) sizeof(ptrLibro));
if (biblio.libptr != NULL)
rcode = 0;
}
else {
/*
* Definir array de n libros
*/
biblio.libarr = (ptrLibro) calloc(n, (int) sizeof(Libro));
if (biblio.libarr != NULL)
rcode = 0;
}
return rcode;
}
Eliminar biblioteca: void freeBiblio(void)¶
/*
* Libera la memoria (din谩mica) asociada con la biblioteca
* Seg煤n el modo libera memoria del array de libros
* o del array de punteros a libros
*/
void freeBiblio(void) {
int i;
if(biblio.modo == '0') {
/*
* Liberar memoria n libros. Requiere iterar en array de punteros a libros
*/
for(i = 0; i < (int)biblio.lnum; i++)
free(biblio.libptr[i]);
/*
* Liberar memoria array de punteros. No requiere iterar
*/
free(biblio.libptr);
}
else
/*
* Liberar memoria array de libros
*/
free(biblio.libarr);
}
Crear libro: ptrLibro newLibro(int isbn, char *titulo, char *autor, char *descripcion)¶
/*
* C贸digo equivalente a la declaraci贸n est谩tica de
* un libro pero utilizando memoria din谩mica
* Declaraci贸n est谩tica: Libro miLibro;
*/
ptrLibro newLibro(int isbn, char *titulo, char *autor, char *descripcion) {
ptrLibro plibro;
/*
* Creaci贸n de un libro reservando memoria de forma din谩mica invocando calloc (malloc + init)
* OJO: los datos del libro suministrados como argumento se copian al nuevo libro
*/
plibro = (ptrLibro) calloc (1, sizeof(Libro));
if (plibro != NULL) {
plibro->isbn = isbn;
strcpy(plibro->titulo, titulo);
strcpy(plibro->autor, autor);
strcpy(plibro->descripcion, descripcion);
}
return plibro;
}
Obtener libro n de la biblioteca (getter): ptrLibro getLibro(int n)¶
/*
* getter Libro. Devuelve su direcci贸n en la biblioteca
*/
ptrLibro getLibro(int n) {
ptrLibro aux;
if(n > 0 && n < (int)biblio.lnum +1) {
/*
* Discriminar modo
*/
if(biblio.modo == '0')
/*
* Devuelve el puntero en el array de punteros
*/
aux = biblio.libptr[n - 1];
else
/*
* Devuelve la direcci贸n en el array de libros
*/
aux = &biblio.libarr[n - 1];
return aux;
}
return NULL;
}
A帽adir libro a biblioteca (setter): int putLibro(ptrLibro p)¶
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | |
Redimensionar la biblioteca: int masBiblio(int n)¶
/*
* Ampl铆a la biblioteca para acomodar n libros adicionales
* Devuelve 0 si se ampl铆a y 1 en caso contrario
*/
int masBiblio(int n) {
int rcode = 1;
ptrLibro *aux1, aux2;
if(biblio.modo == '0') {
/*
* Redimensionar array de n punteros a libros (OJO: sizeof de puntero)
*/
aux1 = (ptrLibro *) realloc(biblio.libptr, (biblio.lmax + n) * (int) sizeof(ptrLibro));
if (aux1 != NULL) {
biblio.libptr = aux1;
/*
* Incrementar la capacidad en n libros adicionales
*/
biblio.lmax += n;
rcode = 0;
}
}
else {
/*
* Redimensionar array de n libros
*/
aux2 = (ptrLibro) realloc(biblio.libarr, (biblio.lmax + n) * (int) sizeof(Libro));
if (aux2 != NULL) {
biblio.libarr = aux2;
/*
* Incrementar la capacidad en n libros adicionales
*/
biblio.lmax += n;
rcode = 0;
}
}
return rcode;
}
Tarea¶
Abordar las siguientes modificaciones de la funcionalidad del programa
- Importaci贸n de los libros a la biblioteca desde un archivo con datos tipo texto
- Exportaci贸n de los libros a la biblioteca a un archivo con datos tipo texto
- Importaci贸n de los libros a la biblioteca desde un archivo con datos tipo binario
- Exportaci贸n de los libros a la biblioteca a un archivo con datos tipo binario
-
El c贸digo de masBiblio() contempla 煤nicamente incrementar la capacidad de la biblioteca
Una soluci贸n m谩s general debiera permitir tanto aumentar como reducir la capacidad -
Ajustar la memoria requerida por el programa al tama帽o exacto de cada libro. Para ello se requiere redefinir el tipo Libro de acuerdo a la siguiente declaraci贸n
typedef struct Libros { int isbn; char *titulo; char *autor; char *descripcion; } Libro;