#include #include #include #define EXIT_SUCCESS 0 #define EXIT_WRONGCOMMANDLINE 1 #define EXIT_MEMORY 2 #define EXIT_OPENFILE 3 #define RIGA 80 enum _boolean { FALSE = 0, TRUE = 1}; typedef enum _boolean boolean; typedef struct _elemlibro elemlibro; typedef elemlibro *listalibri; typedef elemlibro *poslibro; struct _elemlibro { char AutoreTitolo[RIGA]; elemlibro *next, *prev; }; #define NO_ELEMENT NULL #define NO_LIST NULL listalibri crealista (); void distruggelista (listalibri *pL); poslibro primolista (listalibri L); poslibro ultimolista (listalibri L); boolean finelista (poslibro p, listalibri L); boolean listavuota (listalibri L); poslibro succlista (poslibro p, listalibri L); poslibro preclista (poslibro p, listalibri L); char *leggilista (poslibro p, listalibri L); void scrivilista (char *AutoreTitolo, poslibro p, listalibri L); void inslista (char *AutoreTitolo, poslibro p, listalibri L); void canclista (poslibro *p, listalibri L); void LeggeLineaComando (int argc, char *argv[], char *BiblioFile, char *RecordFile); listalibri CaricaBiblioteca (char *BiblioFile); void EsegueMovimenti (char *RecordFile, listalibri Scaffale, listalibri Prestati, listalibri Resi); void RiponeLibri (listalibri Scaffale, listalibri Resi); poslibro TrovaLibro (char *AutoreTitolo, listalibri L); void StampaListaLibri (listalibri L); int main(int argc, char *argv[]) { char BiblioFile[RIGA], RecordFile[RIGA]; listalibri Scaffale; listalibri Prestati; listalibri Resi; // 1) Interpretazione della linea di comando LeggeLineaComando(argc,argv,BiblioFile,RecordFile); // 2) Caricamento dei dati Scaffale = CaricaBiblioteca(BiblioFile); // 3) Allocazione delle strutture dati ausiliarie Prestati = crealista(); Resi = crealista(); // 4a) Algoritmo 1 (registrazione di prestiti e rese) EsegueMovimenti(RecordFile,Scaffale,Prestati,Resi); // 6a) Stampa dei libri rimasti StampaListaLibri(Scaffale); // 4b-6b) Algoritmo 2 (riordino della biblioteca) e stampa delle istruzioni RiponeLibri(Scaffale,Resi); // 5) Deallocazione delle strutture dati ausiliarie distruggelista(&Prestati); distruggelista(&Resi); // 6c) Stampa dei libri rimasti StampaListaLibri(Scaffale); // 7) Deallocazione dei dati distruggelista(&Scaffale); return EXIT_SUCCESS; } void LeggeLineaComando (int argc, char *argv[], char *BiblioFile, char *RecordFile) { if (argc != 3) { printf("Il formato della linea di comando e' errato!\n"); exit(EXIT_WRONGCOMMANDLINE); } strcpy(BiblioFile,argv[1]); strcpy(RecordFile,argv[2]); } listalibri CaricaBiblioteca (char *BiblioFile) { FILE *fBiblioFile; char Riga[RIGA]; listalibri Scaffale; fBiblioFile = fopen(BiblioFile,"r"); if (fBiblioFile == NULL) { printf("Errore nell'apertura del file %s!\n",BiblioFile); exit(EXIT_OPENFILE); } Scaffale = crealista(); fgets(Riga,RIGA,fBiblioFile); while (strcmp(Riga,"FINE\n") != 0) { // Elimina l'a capo dalla stringa Riga[strlen(Riga)-1] = '\0'; // Inserisce il nuovo libro in coda allo scaffale inslista(Riga,succlista(ultimolista(Scaffale),Scaffale),Scaffale); fgets(Riga,RIGA,fBiblioFile); } fclose(fBiblioFile); return Scaffale; } void EsegueMovimenti (char *RecordFile, listalibri Scaffale, listalibri Prestati, listalibri Resi) { FILE *fRecordFile; char Comando[RIGA], Riga[RIGA]; poslibro p; fRecordFile = fopen(RecordFile,"r"); if (fRecordFile == NULL) { printf("Errore nell'apertura del file %s!\n",RecordFile); exit(EXIT_OPENFILE); } fscanf(fRecordFile,"%s ",Comando); while (strcmp(Comando,"FINE") != 0) { fgets(Riga,RIGA,fRecordFile); Riga[strlen(Riga)-1] = '\0'; if (strcmp(Comando,"PRESTITO") == 0) { // Cerca il libro sullo scaffale e lo cancella p = TrovaLibro(Riga,Scaffale); if (p != NO_ELEMENT) canclista(&p,Scaffale); // Inserisce il nuovo libro in coda alla lista dei prestiti inslista(Riga,succlista(ultimolista(Prestati),Prestati),Prestati); } else if (strcmp(Comando,"RESTITUZIONE") == 0) { // Cerca il libro nella lista dei prestiti e lo cancella p = TrovaLibro(Riga,Prestati); if (p != NO_ELEMENT) canclista(&p,Prestati); // Inserisce il libro in cima alla lista dei resi inslista(Riga,primolista(Resi),Resi); } fscanf(fRecordFile,"%s ",Comando); } fclose(fRecordFile); } void RiponeLibri (listalibri Scaffale, listalibri Resi) { } poslibro TrovaLibro (char *AutoreTitolo, listalibri L) { return NO_ELEMENT; } void StampaListaLibri (listalibri L) { poslibro p; printf("SCAFFALE\n"); for (p = primolista(L); !finelista(p,L); p = succlista(p,L) ) printf("%s\n",leggilista(p,L)); printf("FINE\n"); } listalibri crealista () { listalibri L = (listalibri) malloc(sizeof(elemlibro)); if (L == NULL) { printf("Memoria insufficiente per allocare la lista dei libri!\n"); exit(EXIT_MEMORY); } L->next = L; L->prev = L; return L; } void distruggelista (listalibri *pL) { poslibro p; for (p = primolista(*pL); !listavuota(*pL); canclista(&p,*pL)); free(*pL); *pL = NULL; } poslibro primolista (listalibri L) { poslibro p = L->next; return p; } poslibro ultimolista (listalibri L) { poslibro p = L->prev; return p; } boolean finelista (poslibro p, listalibri L) { boolean b = (boolean) (p == L); return b; } boolean listavuota (listalibri L) { boolean b = (boolean) ( (L->next == L) && (L->prev == L) ); return b; } poslibro succlista (poslibro p, listalibri L) { poslibro q = p->next; return q; } poslibro preclista (poslibro p, listalibri L) { poslibro q = p->prev; return q; } char *leggilista (poslibro p, listalibri L) { return p->AutoreTitolo; } void scrivilista (char *AutoreTitolo, poslibro p, listalibri L) { strcpy(p->AutoreTitolo,AutoreTitolo); } void inslista (char *AutoreTitolo, poslibro p, listalibri L) { poslibro q = (poslibro) malloc(sizeof(elemlibro)); if (q == NULL) { printf("Memoria insufficiente per allocare il libro %s!\n",AutoreTitolo); exit(EXIT_MEMORY); } scrivilista(AutoreTitolo,q,L); q->prev = p->prev; q->next = p; p->prev->next = q; p->prev = q; } void canclista (poslibro *pp, listalibri L) { poslibro q; q = *pp; q->prev->next = q->next; q->next->prev = q->prev; *pp = q->next; free(q); }