Salve a tutti, seguo questo forum da molto tempo e mi è sempre stato molto ultile, questa è la prima volta che scrivo un messaggio! così colgo l'occasione per ringraziare gli utenti
Ora vengo al dunque:
Mi è stato posto il problema di creare un programma che funzioni da catalogatore per una biblioteca.
E' richiesto far uso delle liste concatenate per contenere i dati di ogni singolo libro e di dare la possiblità all'utente di inserire, eliminare, e ricercare certi libri in base a parole chiave. Penso di essere a buon punto, però si verifica un'errore che non riesco proprio a capire. Vi posto la parte essenziale del codice e poi torno a commentare in basso:
(Ho eliminato le funzioni di ricerca perchè non possono influire sul problema, si verifica anche non utilizzandole affatto)
Vi spiego brevemente quello che accade:codice:#include <stdio.h> #include <stdlib.h> #include <string.h> #define SIZE 10 typedef struct Libro *lista; typedef struct Libro{ int ID; char Autore[255]; char Titolo[255]; char Parole[255]; lista next; } Libro; Libro * newLibro(void); // Restituisce un puntatore ad un nuovo libro allocato. void makeMenu(int *select); // Stampa il menu e acquisice la scelta. void destLibri(Libro *p); // Dealloca tutta la lista. void stampLibri(Libro *p); // Stampa la lista completa. void remLibri(Libro *p, int nLibri); // Rimuove il libro selezionato dall'elenco. void add2tail(Libro *p, Libro *new); // Aggiunge un elemento in coda. int countlibri(Libro *p); // Conta gli elementi della lista. int main(int argc, char *argv) { int select, nLibri, mod; Libro *inizio = (Libro *) malloc(sizeof(Libro)); Libro *p; do{ //cicla fino a quando l'utente decide di terminare. makeMenu(&select); while (getchar() != '\n'); switch(select){ case 0: //exit break; case 1: //alloca libro, lo accoda e aggiorna nLibri if(nLibri<SIZE){ p = newLibro(); add2tail(inizio, p); nLibri = countlibri(inizio); printf("Libro inserito correttamente(%d/%d).\n", nLibri, SIZE); }else printf("Lo spazio sugli scaffali della biblioteca è esaurito.\n"); break; case 2: //stampa lista if(nLibri!=0) stampLibri(inizio->next); else printf("Non ci sono libri.\n"); break; case 5: //rimuove un libro dalla lista, aggiorna nLibri if(nLibri!=0){ remLibri(inizio, nLibri); nLibri = countlibri(inizio); printf("Libro rimosso con successo(%d/%d).\n", nLibri, SIZE); }else printf("Non ci sono libri.\n"); break; } }while(select != 0); destLibri(inizio); return 0; } void makeMenu(int *select) { printf("\t\t==M E N U==\n" "0- Esci.\n1- Inserisci Libro.\n2- Visualizza Libri.\n3- Ricerca libri(1+ matching).\n4- Ricerca libri(full matching).\n5- Rimuovi libro.\n>"); scanf("%d", select); } Libro * newLibro(void) { Libro *p; p= (Libro *) malloc(sizeof(Libro)); printf("Inserire l'ID del libro: "); scanf("%d", &p->ID); while (getchar() != '\n'); //per pulire il buffer dopo scanf printf("Inserire l'Autore: "); fgets(p->Autore, 255, stdin); printf("Inserire il Titolo: "); fgets(p->Titolo, 255, stdin); printf("Inserire le 5 parole chiavi, separate da spazi: "); fgets(p->Parole, 255, stdin); return p; } int countlibri(Libro *p) { int i = 0; while(p->next != NULL ){ //<<SI BLOCCA QUI i++; p = p->next; } return i; } void add2tail(Libro *p, Libro *new) { while(p->next) p = p->next; p->next = new; } void destLibri(Libro *p) { if(p == NULL) return; Libro *temp; temp = p->next; free(p); destLibri(temp); } void stampLibri(Libro *p) { int i = 1; while(p){ printf("========\nLibro (%d/%d):\nID: %d\nAutore: %sTitolo: %s========\n", i, SIZE, p->ID, p->Autore, p->Titolo); p = p->next; i++; } } void remLibri(Libro *p, int nLibri) { Libro *temp; int i, n; stampLibri(p->next); do{ printf("Inserisci il numero in elenco del libro da rimuovere(1/%d): ", nLibri); scanf("%d", &n); }while(n<1 || n>nLibri); for(i=0; i < n-1; i++) p = p->next; //scorre fino al libro prima di quello da eliminare temp = p->next; p->next = temp->next; free(temp); }
Dopo aver elminato un'elemento dalla lista (che non sia l'ultimo), quando vado a creare un nuovo elemento. la funzione countlibri entra in un loop infinito, e pur sapendo dov'è il problema non capisco proprio cosa lo causi!
Ho analizzato attentamente la funzione remLibri, ma "su carta" il problema non dovrebbe esserci.(almeno credo)
Questa è la prova su carta che ho fatto:
Ipotizziamo una lista composta da:
inizio->libro1->libro2->NULL
così concatenata:
Inizio->next = libro1
libro1->next = libro2
libro2->next = NULL
Il for all'interno della funzione non esegue nulla (i=0 ; n-1=0), quindi siamo fermi ad "Inizio". proseguento passo a passo:
- temp punta a libro1 (quello da eliminare)
- inizio punta al next di libro1 (libro2)
- libero lo spazio a cui punta libro1
Dopo tutto questo però, quando provo ad inserire un nuovo libro countlibri si blocca nel ciclo anche se in teoria il next di libro2 non è stato toccato e punta ancora a NULL. Spero di essermi spiegato in modo comprensibileA presto!


Rispondi quotando
?