PI-ITBA / 2024_01

9 stars 0 forks source link

ejercicio de Taller BibleADT #370

Closed mholgadoo closed 1 week ago

mholgadoo commented 1 week ago

(no encuentro la solucion y por eso pregunto por aca) Esta bien?


*
#define CANT_BOOKS 76
#define IS_VALID_BOOK(size_t bookNbr)((bookNbr) < CANT_BOOKS)

struct bibleCDT{
    TBook books[CANT_BOOKS];
}

typedef struct book{
    TVerse * verses;
    size_t dim;
}TBook;

typedef struct verse{
    char * verse;
    size_t len;
}TVerse;

/* Libera todos los recursos reservados por el TAD */
void freeBible(bibleADT bible){
for (int i = 0; i < CANT_BOOKS; i++){
    for (int j = 0; j < bible->books[i].dim; j++){
        bible->books[i].verses[j];
    }
    bible->books[i];
}
free(bible);
}

typedef struct bibleCDT * bibleADT;

bibleADT newBible(void){
    return calloc(1, sizeof(struct bicleCDT));
}

/*
** Agrega un versículo a la Biblia. Si ya estaba ese número de versículo en ese
** número de libro, no lo agrega ni modifica y retorna 0. Si lo agregó retorna 1 
** bookNbr: número de libro
** verseNbr: número de versículo
*/
int addVerse(bibleADT bible, size_t bookNbr, size_t verseNbr, const char * verse){
    if (!IS_VALID_BOOK(bookNbr)){
        exit(1);
    }
    if (verseNbr >= bible->books[bookNbr - 1].dim){
        //agrego espacio para este versiculo
        bible->books[booksNbr - 1].verses = realloc(bible->books[booksNbr].verses, verseNbr);
        for (int i = bible->books[bookNbr - 1].dim; i < verseNbr; i++){
            bible->books[bookNbr - 1].verses[i] = NULL;
        }
    }
    if (bible->books[bookNbr - 1].verses[verseNbr - 1] == NULL){    
        size_t verseLen = strlen(verse);
        bible->books[booksNbr - 1].verses[verseNbr - 1]->verse = malloc(sizeof(char) * (verseLen + 1))
        strcpy(bible->books[booksNbr - 1].verses[verseNbr - 1]->verse, verse);
        return 1;
    }
    return 0;
}

/*
** Retorna una copia de un versículo o NULL si no existe.
** bookNbr: número de libro
** verseNbr: número de versículo
*/
char * getVerse(bibleADT bible, size_t bookNbr, size_t verseNbr){
    if (!IS_VALID_BOOK(bookNbr)){
        exit(1);
    }
    if (verseNbr >= bible->books[bookNbr - 1].dim && bible->books[bookNbr - 1].verses[verseNbr] != NULL){
        size_t len = bible->books[bookNbr - 1].verses[verseNbr - 1].len;
        char * resp = malloc(sizeof(char) * len + 1);
        strcpy(resp, bible->books[bookNbr - 1].verses[verseNbr - 1].verse);
        return resp;
    }
    return NULL;
}

*
marcelogarberoglio commented 1 week ago

Te paso el programa de prueba básico

int 
main(void) {
    bibleADT b = newBible(); 
    assert(getVerse(b, 1, 1)==NULL);

    char aux[2000];
    strcpy(aux, "En el principio creo Dios los cielos y la tierra.");
    assert(addVerse(b, 1, 1, aux)==1);

    strcpy(aux, "Y atardecio y amanecio: dia tercero.");
    assert(addVerse(b, 1, 13, aux)==1);

    assert(addVerse(b, 1, 13, "Amaos los unos a los otros")==0); // Ya estaba

    strcpy(aux, "los contados de la tribu de Dan fueron sesenta y dos mil setecientos.");
    assert(addVerse(b, 4, 39, aux)==1);

    assert(addVerse(b, 4, 46,
      "fueron todos los contados seiscientos tres mil quinientos cincuenta.")==1);

    char * v = getVerse(b, 4, 45);
    assert(v==NULL);

    v = getVerse(b, 4, 39);
    assert(strncmp(v, "los con", 7)==0);
    free(v);

    freeBible(b);

    puts("Aleluya !");
    return 0;
}

y se mencionó varias veces (en clase) que si los strings son extensos, cuando se almacena se debe copiar de a bloques (hay ejercicios similares en la guía 11)