Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

HELP with Stacks (Cprog.) This a program stores information of the books there a

ID: 3842685 • Letter: H

Question

HELP with Stacks (Cprog.)

This a program stores information of the books there are in a library (code, author, availability..), and not only that but also lets the user to insert new books in its database which will get store in certain manner or to delete existing ones.

In this exercise, we have to define a stack to save units of data of the type Book, and the methods to have access to this stack. We do that by completing the files stack.h and stack.c

The tasks are:

1)To define in stack.h the type of data tBookStack that represents a stack of units of data of the type tBook

2)Implement in stack.c the action:

Void bookStack_create(tBookStack*stack) so given an input/output parameter of the type tBookStack, it initializes this parameter in an empty stack.

I inclue the .h necessary files as ell as the excecutable books.c

Stack.h

#include "data.h"


typedef struct {
} tBookStack;

void bookStack_create(tBookStack *stack);

tBoolean bookStack_empty(tBookStack stack);

tError bookStack_push(tBookStack *stack, tBook newElement);

tError bookStack_pop (tBookStack *stack, tBook *element);

void bookStack_transfer(tBookStack *stack_dest, tBookStack *stack);

tError bookStack_search(tBookStack *stack, char *ISBN, tBook *book);

Stack.c

#include "books.h"
#include "stack.h"
#include <string.h>


void bookStack_create(tBookStack *stack) {

}

Books.h

#include "data.h"

/* Get a textual representation of a book */
void getBookStr(tBook book, int maxSize, char *str);
   
/* Get a book object from its textual representation */
tError getBookObject(const char *str, tBook *book);

/* Compare two books by author name*/
int book_cmp(tBook t1, tBook t2);

/* Copy the book data in src to dst*/
void book_cpy(tBook *dst, tBook src);

/* Initialize the table of books */
void bookTable_init(tBookTable *bookTable);

/* Add a new book to the table of books */
tError bookTable_add(tBookTable *table, tBook book);

/* Find a book in the table */
int bookTable_find(tBookTable table, char *ISBN);

/* Remove the first occurence of a book in the table */
void bookTable_del(tBookTable *table, tBook book);

/* Load the table of books from a file */
tError bookTable_load(tBookTable *table, const char* filename);

/* Save a table of books to a file */
tError bookTable_save(tBookTable table, const char* filename);

void bookTable_filterBySection(

tBookTable tabBook, char sectionID, tBookTable *result);

unsigned int bookTable_getOnLoanNumber(tBookTable tabBook);

unsigned int bookTable_getAuthorNumber(tBookTable tabBook, char *author);

tError bookTable_sortedAdd(tBookTable *tabBook, tBook book);

void bookTable_sort(tBookTable tabBook, tBookTable *result);

/* Release a books table */
void bookTable_release(tBookTable *table);

Data.h

#define SIMPLE_VERSION
//#define COMPLETE_VERSION

/* This code ensures that this file is included only once */
#ifndef __DATA_H
#define __DATA_H
/* If the constant DATA_H is not defined (ifndef), the code is added, otherwise, this code is excluded. When the code is added, the constant is defined, therefore next time this file will be included it will be defined and no inclusion will be done. */

#define MAX_PATHNAME 256
#define MAX_LINE 512
#define MAX_SECTIONS 10
#define MAX_SECTION_NAME 100
#define MAX_BOOKS 300
#define MAX_SUB 10
#define MAX_BOOK_ISBN 14
#define MAX_BOOK_AUTHOR_CODE 4
#define MAX_BOOK_TITLE 101

/* Definition of a boolean type */
typedef enum {FALSE, TRUE} tBoolean;

/* Definition of the error type. */
typedef enum {OK=1, ERROR=0, ERR_CANNOT_READ=-1, ERR_CANNOT_WRITE=-2, ERR_MEMORY=-3, ERR_DUPLICATED_ENTRY=-4, ERR_INVALID_DATA=-5, ERR_ENTRY_NOT_FOUND=-6} tError;

/* Definition of a location */
typedef struct {
    char row;
    char column;
    char shelf;
} tLocation;

/* Definition of a section */
typedef struct {
    char id;
    char name[MAX_SECTION_NAME];
    tLocation init;
} tSection;

/* Table of sections */
typedef struct {
    tSection table[MAX_SECTIONS];
    int size;
} tSectionTable;

/* Definition of a classification */
typedef struct {
    char secId;
    char subId;
} tClass;

/* Definition of the book */
typedef struct {
    char ISBN[MAX_BOOK_ISBN];
    unsigned short year;
    tBoolean avail;
    tClass clas;
    char author[MAX_BOOK_AUTHOR_CODE];
    char title[MAX_BOOK_TITLE];
} tBook;

/* Table of books */
typedef struct {
#ifdef SIMPLE_VERSION
    tBook table[MAX_BOOKS];
#endif
#ifdef COMPLETE_VERSION

#endif   
    int size;
} tBookTable;


/* Definition of the application data structure */
typedef struct {
    /* Path where data will be stored */
    char path[MAX_PATHNAME];
   
    /* sections table */
    tSectionTable sections;
   
    /* Books table */
    tBookTable books;
   
} tAppData;


/* Books of a class */
typedef struct {
    char id;
    /* Table of books of the subsection */
#ifdef SIMPLE_VERSION   
#endif   
#ifdef COMPLETE_VERSION   

#endif
} tSubInfo;

/* Classes of a section */
typedef struct {
    unsigned int totSecSubs;
} tSectionInfo;

#endif /*__DATA_H*/

Books.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "books.h"


void getBookStr(tBook book, int maxSize, char *str) {
    int length;
    unsigned short int tmpAvail;
   
    if (book.avail==TRUE)
        tmpAvail=1;
    else
        tmpAvail=0;
       
    length = snprintf(str,maxSize-1,"%s %hu %hu %c %c %s %s", book.ISBN, book.year, tmpAvail, book.clas.secId, book.clas.subId, book.author, book.title);
    if (length>0)
        str[length]='';
}

tError getBookObject(const char *str, tBook *book) {

    tError retVal = OK;
    unsigned short int tmpAvail;
   
    sscanf(str, "%s %hu %hu %c %c %s %s", book->ISBN, &book->year, &tmpAvail, &book->clas.secId, &book->clas.subId, book->author, book->title);
   
    book->avail = (tmpAvail==1);

    return retVal;
}

void bookTable_init(tBookTable *bookTable) {
    bookTable->size=0;
#ifdef COMPLETE_VERSION
/******************** PR2 - EX6C ********************/
#endif
}

int book_cmp(tBook b1, tBook b2) {
   
    int retVal=0;
   
    if (b1.clas.secId>b2.clas.secId) retVal = 1;
    else if (b1.clas.secId<b2.clas.secId) retVal = -1;
    else {
        if (b1.clas.subId>b2.clas.subId) retVal = 1;
        else if (b1.clas.subId<b2.clas.subId) retVal = -1;
        else {
            retVal = strcmp(b1.author, b2.author);
            if(retVal==0) {
                /* If the author is equal, order by title */
                retVal=strcmp(b1.title, b2.title);
                if (retVal==0)
                    retVal=strcmp(b1.ISBN,b2.ISBN);
            }
        }
    }
   
    return retVal;
}

void book_cpy(tBook *dst, tBook src) {
    strcpy(dst->ISBN,src.ISBN);
    dst->year = src.year;
    dst->avail = src.avail;
    dst->clas.secId = src.clas.secId;
    dst->clas.subId = src.clas.subId;
    strcpy(dst->author, src.author);
    strcpy(dst->title, src.title);
}

tError bookTable_add(tBookTable *tabBook, tBook book) {

    tError retVal = OK;

#ifdef SIMPLE_VERSION
    /* Check if there enough space for the new book */
    if(tabBook->size>=MAX_BOOKS) {
        retVal = ERR_MEMORY;
    }
#endif
#ifdef COMPLETE_VERSION
/******************** PR2 - EX6D ********************/
#endif
    if (retVal==OK){
    /* Add the new book to the end of the table */
        book_cpy(&(tabBook->table[tabBook->size]), book);   
        tabBook->size++;
    }

    return retVal;
}

int bookTable_find(tBookTable tabBook, char *ISBN) {
    int i;
    int idx = -1;
   
    i=0;
    while(i< tabBook.size && idx==-1) {
        /* Check if the id is the same */
        if(strcmp(tabBook.table[i].ISBN,ISBN)==0) {
            /* Get the position of the match */
            idx = i;
        }
        i++;
    }
   
    return idx;
}

void bookTable_del(tBookTable *tabBook, tBook book) {
    int i;
    int pos;

    pos = bookTable_find(*tabBook,book.ISBN);
    if (pos!=-1){
    /* If the book is found, all the rest of the elements are displaced one position */
        for(i=pos;i<tabBook->size-1; i++) {       
            book_cpy(&(tabBook->table[i]), tabBook->table[i+1]);           
        }
        tabBook->size=tabBook->size-1;   
#ifdef COMPLETE_VERSION
/******************** PR2 - EX6E ********************/
#endif
    }
}

tError bookTable_save(tBookTable tabBook, const char* filename) {
    FILE *fout=0;
    int i;
    char str[MAX_LINE];
    tError retVal = OK;
   
    /* Open the output file */
    if((fout=fopen(filename, "w"))!=0) {

        /* Save all books to the file */
        for(i=0;i<tabBook.size;i++) {
            getBookStr(tabBook.table[i], MAX_LINE, str);
            fprintf(fout, "%s ", str);
        }
       
        /* Close the file */
        fclose(fout);
        retVal = OK;
    } else {
        retVal = ERR_CANNOT_WRITE;
    }
   
    return retVal;
}

tError bookTable_load(tBookTable *tabBook, const char* filename) {

    tError retVal = OK;
    FILE *fin=0;   
    char line[MAX_LINE];
    tBook newBook;
   
    /* Initialize the output table */
    bookTable_init(tabBook);
   
    /* Open the input file */
    if((fin=fopen(filename, "r"))==0) {
        retVal = ERR_CANNOT_READ;
    }
   
    /* Read all the books */
    while(retVal==OK && !feof(fin) && tabBook->size<MAX_BOOKS) {
        /* Remove any content from the line */
        line[0] = '';
        /* Read one line and store it in "line" variable */
        fgets(line, MAX_LINE-1, fin);
        /* Ensure that the string is ended by 0*/
        line[MAX_LINE - 1]='';
        if(strlen(line)>0) {
            /* Obtain the object */
            getBookObject(line, &newBook);
            /* Add the new book to the output table */
            bookTable_add(tabBook, newBook);       
        }
    }   
       
    /* Close the file */
    fclose(fin);
   
    return retVal;
}


void bookTable_filterBySection(tBookTable tabBook, char sectionId, tBookTable *result) {
    int i;
   
    bookTable_init(result);
    i=0;
    while(i< tabBook.size) {
        /* Check if the section is the same */
        if(tabBook.table[i].clas.secId==sectionId) {
            /* Add to the result table */
            bookTable_add(result,tabBook.table[i]);
        }
        i++;
    }
}

unsigned int bookTable_getOnLoanNumber(tBookTable tabBook){
    unsigned int i;
    unsigned int numBooks=0;
   
    i=0;
    while(i< tabBook.size) {
        /* Check if the book is not available */
        if(tabBook.table[i].avail!=TRUE) {
            /* Add a unit to the total */
            numBooks++;
        }
        i++;
    }
   
    return numBooks;
}

unsigned int bookTable_getAuthorNumber(tBookTable tabBook, char *author){
    unsigned int i;
    unsigned int numBooks=0;
   
    i=0;
    while(i< tabBook.size) {
        /* Check if the author matches */
        if(strcmp(tabBook.table[i].author,author)==0) {
            /* Add a unit to the total */
            numBooks++;
        }
        i++;
    }
   
    return numBooks;
}

/******************** PR2 - EX1A ********************/
tError bookTable_sortedAdd(tBookTable *tabBook, tBook book){
    tError retVal = OK;

    /* Check if there enough space for the new book */
#ifdef SIMPLE_VERSION

#endif
#ifdef COMPLETE_VERSION
/******************** PR2 - EX6D ********************/
#endif

   
    return retVal;   
}

/******************** PR2 - EX1B ********************/
void bookTable_sort(tBookTable tabBook, tBookTable *result){

}

/* Release a books table */
void bookTable_release(tBookTable *tabBook) {
#ifdef COMPLETE_VERSION
/******************** PR2 - EX6F ********************/
#endif  

Explanation / Answer

stack.h

#include "data.h"

/******************** PR2 - EX4A ********************/
typedef struct {
   tBook pile[MAX_BOOKS];
   int size;
} tBookStack;

void bookStack_create(tBookStack *stack);

tBoolean bookStack_empty(tBookStack stack);

tError bookStack_push(tBookStack *stack, tBook newElement);

tError bookStack_pop (tBookStack *stack, tBook *element);

void bookStack_transfer(tBookStack *stack_dest, tBookStack *stack);

tError bookStack_search(tBookStack *stack, char *ISBN, tBook *book);

main.c

#include <stdio.h>
#include <string.h>
#include "menu.h"
#include "test.h"

int main(int argc, char **argv)
{
   int i;
   tBoolean testMode=FALSE;
   tAppData appData;
  
   setbuf(stdout, NULL);
   appData_init(&appData);
          
   for(i=1; i<argc; i++) {
       if(strcmp(argv[i], "-t")==0) {
           testMode=TRUE;          
       }
   }
   if(testMode) {
       runTests();
   } else {
       mainMenu(&appData);
   }
  
   return 0;
}

api.c

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <api.h>
#include "books.h"
#include "sections.h"

void appData_init(tAppData *object) {
   strcpy(object->path, "../");
   bookTable_init(&(object->books));
   secTable_init(&(object->sections));

}

tError appData_load(tAppData *object) {
   char path[MAX_LINE];
   tError retVal = OK;
   sprintf(path,"%ssections.txt", object->path);
   retVal=secTable_load(&(object->sections), path);
   if(retVal!=OK) {
       printf("ERROR: Error reading the file of sections ");
   }
sprintf(path,"%sbooks.txt", object->path);
   retVal=bookTable_load(&(object->books), path);
   if(retVal!=OK) {
       printf("ERROR: Error reading the file of books ");
   }
  
   return retVal;
}

tError appData_save(tAppData object) {
   char path[MAX_LINE];
   tError retVal = OK;
   sprintf(path,"%ssections.txt", object.path);
   retVal=secTable_save(object.sections, path);
   if(retVal!=OK) {
       printf("ERROR: Error saving the file of sections ");
   }
   sprintf(path,"%sbooks.txt", object.path);
   retVal=bookTable_save(object.books, path);
   if(retVal!=OK) {
       printf("ERROR: Error saving the file of books ");
   }
  
   return retVal;
}

void appData_setPath(tAppData *object, const char *path) {      
   strncpy(object->path, path, 255);  
}
tError getSections(tAppData object, tSectionTable *result) {
   tError retVal = OK;
   *result = object.sections;  
   return retVal;
}

tError getSection(tAppData object, char sectionId, tSection *section) {
  
   tError retVal = OK;
   tBoolean found;
   int i;
  
   found = FALSE;
   /* Check if there is another section with this ID */
   for(i=0; i<object.sections.size; i++) {
       if(object.sections.table[i].id==sectionId) {
           section_cpy(section,object.sections.table[i]);
       }
   }
   if (!found) retVal = ERR_ENTRY_NOT_FOUND;
  
   return retVal;
}

tError addSection(tAppData *object, tSection section) {
   tError retVal = OK;
   tSection tmp;
   if(getSection(*object, section.id, &tmp)==OK) {
       retVal = ERR_DUPLICATED_ENTRY;
   } else {
       retVal =secTable_add(&(object->sections), section);
   }
   return retVal;
}

tError getBooks(tAppData object, tBookTable *result) {
   tError retVal = OK;
   *result = object.books;  
   return retVal;
}

tError getBook(tAppData object, char *ISBN, tBook *book) {
  
   int i;
   tError retVal = OK;
   i = bookTable_find(object.books, ISBN);
   if (i!=-1) {
       book_cpy(book,object.books.table[i]);
   } else {
       retVal = ERR_ENTRY_NOT_FOUND;
   }
  
   return retVal;
}


tError addBook(tAppData *object, tBook book) {
   tError retVal = OK;
   retVal=bookTable_add(&(object->books), book);  
  
   return retVal;
}

tError removeBook(tAppData *object, tBook book) {
   /* Call the method from the book table*/
   bookTable_del(&(object->books), book);
   return OK;
}
void appData_release (tAppData *object) {
#ifdef COMPLETE_VERSION
/******************** PR2 - EX6F ********************/
   if(object->books.table!=0) {
       free(object->books.table);
       object->books.table=NULL;
       object->books.size=0;
   }
  
   if(object->sections.table!=0) {
       free(object->sections.table);
       //object->sections=NULL;
       object->sections.size=0;
   }
  
  
#endif  
}

books.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "books.h"

void getBookStr(tBook book, int maxSize, char *str) {
   int length;
   unsigned short int tmpAvail;
  
   if (book.avail==TRUE)
       tmpAvail=1;
   else
       tmpAvail=0;
      
   length = snprintf(str,maxSize-1,"%s %hu %hu %c %c %s %s", book.ISBN, book.year, tmpAvail, book.clas.secId, book.clas.subId, book.author, book.title);
   if (length>0)
       str[length]='';
}

tError getBookObject(const char *str, tBook *book) {

   tError retVal = OK;
   unsigned short int tmpAvail;
  
   sscanf(str, "%s %hu %hu %c %c %s %s", book->ISBN, &book->year, &tmpAvail, &book->clas.secId, &book->clas.subId, book->author, book->title);
  
   book->avail = (tmpAvail==1);

   return retVal;
}

void bookTable_init(tBookTable *bookTable) {
   bookTable->size=0;
#ifdef COMPLETE_VERSION
/******************** PR2 - EX6C ********************/
   bookTable->table = NULL;
#endif
}

int book_cmp(tBook b1, tBook b2) {
  
   int retVal=0;
  
   if (b1.clas.secId>b2.clas.secId) retVal = 1;
   else if (b1.clas.secId<b2.clas.secId) retVal = -1;
   else {
       if (b1.clas.subId>b2.clas.subId) retVal = 1;
       else if (b1.clas.subId<b2.clas.subId) retVal = -1;
       else {
           retVal = strcmp(b1.author, b2.author);
           if(retVal==0) {
               /* If the author is equal, order by title */
               retVal=strcmp(b1.title, b2.title);
               if (retVal==0)
                   retVal=strcmp(b1.ISBN,b2.ISBN);
           }
       }
   }
  
   return retVal;
}

void book_cpy(tBook *dst, tBook src) {
   strcpy(dst->ISBN,src.ISBN);
   dst->year = src.year;
   dst->avail = src.avail;
   dst->clas.secId = src.clas.secId;
   dst->clas.subId = src.clas.subId;
   strcpy(dst->author, src.author);
   strcpy(dst->title, src.title);
}

tError bookTable_add(tBookTable *tabBook, tBook book) {

   tError retVal = OK;

#ifdef SIMPLE_VERSION
   if(tabBook->size>=MAX_BOOKS) {
       retVal = ERR_MEMORY;
   }
#endif
#ifdef COMPLETE_VERSION
   if(tabBook->table==NULL) {
       tabBook->table=(tBook*)malloc(sizeof(tBook));
   } else {
       tabBook->table=(tBook*)realloc(tabBook->table, (tabBook->size+1)*sizeof(tBook));
   }
   if(tabBook->size>=MAX_BOOKS) {
       return ERR_MEMORY;
   }


#endif
   if (retVal==OK){
   /* Add the new book to the end of the table */
       book_cpy(&(tabBook->table[tabBook->size]), book);  
       tabBook->size++;
   }

   return retVal;
}

int bookTable_find(tBookTable tabBook, char *ISBN) {
   int i;
   int idx = -1;
  
   i=0;
   while(i< tabBook.size && idx==-1) {
       /* Check if the id is the same */
       if(strcmp(tabBook.table[i].ISBN,ISBN)==0) {
           /* Get the position of the match */
           idx = i;
       }
       i++;
   }
  
   return idx;
}

void bookTable_del(tBookTable *tabBook, tBook book) {
   int i;
   int pos;

   pos = bookTable_find(*tabBook,book.ISBN);
   if (pos!=-1){
   /* If the book is found, all the rest of the elements are displaced one position */
       for(i=pos;i<tabBook->size-1; i++) {      
           book_cpy(&(tabBook->table[i]), tabBook->table[i+1]);          
       }
       tabBook->size=tabBook->size-1;  
#ifdef COMPLETE_VERSION
/******************** PR2 - EX6E ********************/
       if(tabBook->size==0) {
           free(tabBook->table);
           tabBook->table=NULL;
       } else {
           tabBook->table=(tBook*)realloc(tabBook->table, (tabBook->size+1)*sizeof(tBook));
       }
#endif
   }
}

tError bookTable_save(tBookTable tabBook, const char* filename) {
   FILE *fout=0;
   int i;
   char str[MAX_LINE];
   tError retVal = OK;
  
   /* Open the output file */
   if((fout=fopen(filename, "w"))!=0) {

       /* Save all books to the file */
       for(i=0;i<tabBook.size;i++) {
           getBookStr(tabBook.table[i], MAX_LINE, str);
           fprintf(fout, "%s ", str);
       }
      
       /* Close the file */
       fclose(fout);
       retVal = OK;
   } else {
       retVal = ERR_CANNOT_WRITE;
   }
  
   return retVal;
}

tError bookTable_load(tBookTable *tabBook, const char* filename) {

   tError retVal = OK;
   FILE *fin=0;  
   char line[MAX_LINE];
   tBook newBook;
  
   /* Initialize the output table */
   bookTable_init(tabBook);
  
   /* Open the input file */
   if((fin=fopen(filename, "r"))==0) {
       retVal = ERR_CANNOT_READ;
   }
  
   /* Read all the books */
   while(retVal==OK && !feof(fin) && tabBook->size<MAX_BOOKS) {
       /* Remove any content from the line */
       line[0] = '';
       /* Read one line and store it in "line" variable */
       fgets(line, MAX_LINE-1, fin);
       /* Ensure that the string is ended by 0*/
       line[MAX_LINE - 1]='';
       if(strlen(line)>0) {
           /* Obtain the object */
           getBookObject(line, &newBook);
           /* Add the new book to the output table */
           bookTable_add(tabBook, newBook);      
       }
   }  
      
   /* Close the file */
   fclose(fin);
  
   return retVal;
}


void bookTable_filterBySection(tBookTable tabBook, char sectionId, tBookTable *result) {
   int i;
  
   bookTable_init(result);
   i=0;
   while(i< tabBook.size) {
       /* Check if the section is the same */
       if(tabBook.table[i].clas.secId==sectionId) {
           /* Add to the result table */
           bookTable_add(result,tabBook.table[i]);
       }
       i++;
   }
}

unsigned int bookTable_getOnLoanNumber(tBookTable tabBook){
   unsigned int i;
   unsigned int numBooks=0;
  
   i=0;
   while(i< tabBook.size) {
       /* Check if the book is not available */
       if(tabBook.table[i].avail!=TRUE) {
           /* Add a unit to the total */
           numBooks++;
       }
       i++;
   }
  
   return numBooks;
}

unsigned int bookTable_getAuthorNumber(tBookTable tabBook, char *author){
   unsigned int i;
   unsigned int numBooks=0;
  
   i=0;
   while(i< tabBook.size) {
       /* Check if the author matches */
       if(strcmp(tabBook.table[i].author,author)==0) {
           /* Add a unit to the total */
           numBooks++;
       }
       i++;
   }
  
   return numBooks;
}

/******************** PR2 - EX1A ********************/
tError bookTable_sortedAdd(tBookTable *tabBook, tBook book){
   tError retVal = OK;
   unsigned int i;
    tBook bookMemory;

#ifdef SIMPLE_VERSION

   /* Check if there enough space for the new book */
   if(tabBook->size>=MAX_BOOKS) {
       retVal = ERR_MEMORY;
   }
  
   if (retVal == OK) {
      
        //Add book to the table
       bookTable_add(tabBook,book);

        //Check correct order of books
       for(i=0;i<tabBook->size;i++) {
          
           if(book_cmp(tabBook->table[i], book)==1) {
                bookMemory = tabBook->table[i];
                //Delete book of the table
               bookTable_del(tabBook, bookMemory);
              
                // Add deleted book to the end of the table
                bookTable_sortedAdd(tabBook,bookMemory);
           }
       }
   }

   return retVal;

#endif
#ifdef COMPLETE_VERSION
/******************** PR2 - EX6D ********************/
#endif
   /* Check if there enough space for the new book */
   if(tabBook->size>=MAX_BOOKS) {
       retVal = ERR_MEMORY;
   }
  
   if (retVal == OK) {
      
        //Add book to the table
       bookTable_add(tabBook,book);

        //Check correct order of books
       for(i=0;i<tabBook->size;i++) {
          
           if(book_cmp(tabBook->table[i], book)==1) {
                bookMemory = tabBook->table[i];
                //Delete book of the table
               bookTable_del(tabBook, bookMemory);
              
                // Add deleted book to the end of the table
                bookTable_sortedAdd(tabBook,bookMemory);
           }
       }
   }

  
   return retVal;  
}

/******************** PR2 - EX1B ********************/
void bookTable_sort(tBookTable tabBook, tBookTable *result){
   unsigned int i;

   //Inicialitze table
   bookTable_init(result);  

    //Order table
    for(i=0;i<tabBook.size;i++) {
        bookTable_sortedAdd(result,tabBook.table[i]);
    }

}

/* Release a books table */
void bookTable_release(tBookTable *tabBook) {
#ifdef COMPLETE_VERSION
/******************** PR2 - EX6F ********************/
   if(tabBook->table!=0) {
       free(tabBook->table);
       tabBook->table=NULL;
       tabBook->size=0;
   }
#endif  
}

section.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "sections.h"

void getSectionStr(tSection section, int maxSize, char *str) {
   int length;
  
   length = snprintf(str,maxSize-1,"%c %s", section.id, section.name);          
   str[length]='';
}

tError getSectionObject(const char *str, tSection *section) {
   tError retVal = OK;
  
   sscanf(str, "%c %s", &section->id, section->name);

   return retVal;
}

int section_cmp(tSection s1, tSection s2) {
   int retVal = 0;
  
    if (s1.id > s2.id) {
        retVal = 1;
   } else if (s1.id < s2.id) {
        retVal = -1;
    }
  
   return retVal;
}

void section_cpy(tSection *dst, tSection src) {

   dst->id = src.id;
   strcpy(dst->name, src.name);

}


void secTable_init(tSectionTable *tabSec) {
   tabSec->size=0;
}

tError secTable_add(tSectionTable *tabSec, tSection section) {

   tError retVal = OK;
   /* Check if there enough space for the new section */
   if(tabSec->size>=MAX_SECTIONS) {
       retVal = ERR_MEMORY;
   }

   if (retVal == OK){
       /* Add the new section to the end of the table */
       section_cpy(&tabSec->table[tabSec->size],section);
       tabSec->size++;
   }
  
   return retVal;
}


int secTable_find(tSectionTable tabSec, char sectionId) {
   int i;
   int idx = -1;
  
   i=0;
   while(i< tabSec.size && idx==-1) {
       /* Check if the id is the same */
       if(tabSec.table[i].id==sectionId) {
           idx = i;
       }
       i++;
   }
  
   return idx;
}

void secTable_del(tSectionTable *tabSec, tSection section) {
   int i;
    int pos;

   pos = secTable_find(*tabSec,section.id);
   if (pos!=-1){
   /* If the section is found, all the rest of the elements are displaced one position */
       for(i=pos; i<tabSec->size-1; i++) {      
           section_cpy(&tabSec->table[i],tabSec->table[i+1]);
       }
       tabSec->size=tabSec->size-1;      
   }
}


tError secTable_save(tSectionTable tabSec, const char* filename) {
  
   tError retVal = OK;
   FILE *fout=0;
   int i;
   char str[MAX_LINE];
  
   /* Open the output file */
   if((fout=fopen(filename, "w"))==0) {
       retVal = ERR_CANNOT_WRITE;
   } else {
  
        /* Save all sections to the file */
        for(i=0;i<tabSec.size;i++) {
            getSectionStr(tabSec.table[i], MAX_LINE, str);
            fprintf(fout, "%s ", str);
        }
          
        /* Close the file */
        fclose(fout);
   }
  
   return retVal;
}

tError secTable_load(tSectionTable *tabSec, const char* filename) {
  
   tError retVal = OK;
   FILE *fin=0;
   char line[MAX_LINE];
   tSection newSection;
  
   /* Initialize the output table */
   secTable_init(tabSec);
  
   /* Open the input file */
   if((fin=fopen(filename, "r"))!=NULL) {

       /* Read all the sections */
       while(!feof(fin) && tabSec->size<MAX_SECTIONS) {
           /* Remove any content from the line */
           line[0] = '';
           /* Read one line (maximum 511 chars) and store it in "line" variable */
           fgets(line, MAX_LINE-1, fin);
           /* Ensure that the string is ended by 0*/
           line[MAX_LINE-1]='';
           if(strlen(line)>0) {
               /* Obtain the object */
               getSectionObject(line, &newSection);
               /* Add the new section to the output table */
               secTable_add(tabSec, newSection);      
           }
       }
       /* Close the file */
       fclose(fin);
      
   }else {
       retVal = ERR_CANNOT_READ;
   }
  

   return retVal;
}

stack.c

#include <stdio.h>
#include "books.h"
#include "stack.h"
#include <string.h>

/******************** PR2 - EX4B ********************/
void bookStack_create(tBookStack *stack) {
   stack->size=0;
}

/******************** PR2 - EX4C ********************/
tBoolean bookStack_empty(tBookStack stack) {  
   if(stack.size == 0)
       return TRUE;
   else
       return FALSE;
}

/******************** PR2 - EX4D ********************/
tError bookStack_push(tBookStack *stack, tBook newElement) {
   tError retVal = OK;
   int i;
   int pos = 1;

   //Error stack full
   if(stack->size >=MAX_BOOKS){
       retVal = ERR_MEMORY;
  
   //Move all elements one position
   }else if(stack->size > 0){

       for(i=0;i<stack->size; i++) {      
           book_cpy(&(stack->pile[stack->size-i]), stack->pile[stack->size-pos]);
           pos++;
       }
   }
  
   //Add element at the first position
   book_cpy(&(stack->pile[0]), newElement);
   stack->size++;

   return retVal;
}

/******************** PR2 - EX4E ********************/
tError bookStack_pop (tBookStack *stack, tBook *element) {
    tError retVal = OK;
   int i;
  
   book_cpy(element,stack->pile[0]);
  
   //Empty stack
   if(stack->size ==0){
       retVal = ERROR;
  
   //Move all elements one position
   }else {
       for(i=0;i<stack->size; i++) {      
           book_cpy(&(stack->pile[i]), stack->pile[i+1]);          
       }
       stack->size=stack->size-1;  
   }
  
   return retVal;
}

/******************** PR2 - EX5A ********************/
void bookStack_transfer(tBookStack *stack_dest, tBookStack *stack){
   tBook book;

   while (stack->size>0){
       //Remove element from source
       bookStack_pop(stack, &book);
       //Add element to destination
       bookStack_push(stack_dest,book);
   }  
}

/******************** PR2 - EX5B ********************/
tError bookStack_search(tBookStack *stack, char *ISBN, tBook *book){
   tError retVal = OK;
   int found = 0;
   int i;
   int j;


   for(i=0;i<stack->size; i++) {
       //If the ISBN is found
       if(strcmp(stack->pile[i].ISBN, ISBN)== 0){
           found++;
           book_cpy(book, stack->pile[i]);
           stack->size=stack->size-1;  
           //Move books one position
           for(j=i;j<stack->size; j++) {
               book_cpy(&(stack->pile[j]), stack->pile[j+1]);
           }
       }          
   }
  
   if(found == 0) retVal=ERR_ENTRY_NOT_FOUND;
   return retVal;
}