Libreria in C

di il
16 risposte

Libreria in C

Salve a tutti, sono nuovo e spero di essere abbastanza chiaro. dovrei consegnare un programma entro una settimana ma non riesco proprio a venirne a capo quindi spero che voi mi possiate dare una mano.
#include<stdio.h>
#include<string.h>
#define max 500

typedef struct dati_libro{
    int codice;
    char autore[20];
    char titolo[20];
    char chiave[5][50];
}dati_libro;

typedef struct nodo{
    dati_libro *ele;
	struct nodo *next;
}nodo;        

typedef struct biblioteca{
    nodo *lista;
}biblioteca;
        
void inserisci_testa(nodo **testa, dati_libro *libro){
	nodo *new = malloc(sizeof(nodo)); //creazione del nuovo nodo
	new->ele = libro;
	new->next = *testa;               //aggancio in testa
	*testa = new;                     //aggiornamento del puntatore alla testa
}
	 
biblioteca dati;                                

int inserisci_libro(){                               //funzione per inserire i dati del libro
	int aggiungi, i;
  	dati_libro *libro = malloc(sizeof(dati_libro));
    printf("aggiungi dati libro\n");
    printf("inserire codice libro :\n");
	scanf("%d", &libro->codice);
    printf("inserire autore:\n");
    scanf("%s", &libro->autore);
    printf("inserire titolo:\n");
    scanf("%s", &libro->titolo);
    printf("inserire 5 parole chiave\n");
    for(i=0;i<5;i++){                                                //ciclo for per inserire 5 parole chiavi per ogni libro inserito
  	    printf("inserire parola chiave numero %d:\n", i+1);
        scanf("%s", libro->chiave[i]);
        printf("hai inserito: %s\n", libro->chiave[i]);
    }
	inserisci_testa(&dati.lista, libro);
    printf("se vuoi altri dati digita '1', se vuoi terminare digita '0'\n");
    scanf("%d", &aggiungi);
    return aggiungi;
}
                
int inserisci(){
    int aggiungi;
    do{
	    aggiungi = inserisci_libro();
    } while(aggiungi!=0);
}

void stampa(dati_libro *libro){                       
    printf("il codice del libro e': %d\n", libro->codice);
	printf("il titolo del libro e': %s\n", libro->titolo);
	printf("l'autore e': %s\n\n", libro->autore);
}

void visualizza3(){
 	char parola[3][20];
    int a, b, c;
    int count;
    nodo *p;
	printf("per visualizzare il libro cercato inserire 3 parole chiave\n");
    for(a=0;a<3;a++){
        printf("inserire la %d parola chiave\n", a+1);
	    scanf("%s", parola[a]);
    }
	for(p=dati.lista; p!=NULL; p=p->next){ //scorro la lista
	    count=0;
        for(b=0; b<3; b++) //ogni parola chiave cercata
            for(c=0; c<5; c++) //viene confrontata con le 5 parole chiave del libro
            //se la parola corrisponde incremento count e passo alla prossima parola chiave da cercare
                if(strcmp(parola[b], p->ele->chiave[c]) == 0){ 
	                count++; 
	                break;
	            }
        if(count==3) //tutte e tre le parole sono state trovate
            stampa(p->ele);
	 }
}


void visualizza1(){   //funzione per inserire 3 parole chiavi per cercare il libro 
 	char parola[3][20];
    int a, b, c;
    int count;
    nodo *p;
	printf("per visualizzare il libro cercato inserire 3 parole chiave\n");
	for(a=0;a<3;a++){
        printf("inserire la %d parola chiave\n", a+1);
	    scanf("%s", parola[a]);
	}
	for(p=dati.lista; p!=NULL; p=p->next){
	    count=0;
        for(b=0; b<3; b++){
            for(c=0; c<5; c++){
                if(strcmp(parola[b], p->ele->chiave[c])==0){
			  //se una parola corrisponde metto count = 1 e termino il for interno
	                count=1;
				    break;
                }
	        }
		    if(count == 1){
		 		  //se count == 1 stampo i dati e termino il for intermedio
	 		    stampa(p->ele);
		        break;
		    }         
        }
    }
}

void rimuovi_lista(int codice){ //funzione per rimuovere il libro
	nodo *p, *q = NULL;
	for(p=dati.lista; p!=NULL && p->ele->codice != codice; p=p->next)
	    q = p;
    if(p == NULL) //se il libro non è presente nella biblioteca stampo:"..."
        printf("il libro non e' presente nella biblioteca\n");
    else{       //nel caso in cui trovo il libro nella biblioteca tramite la funzione "free" rimuovo il libro dalla biblioteca
        if(q == NULL)
            dati.lista = p->next;
        else
		    q->next = p->next;
		free(p);
		printf("libro #%d rimosso con successo\n", codice);
	}
}

void rimuovi(){
    int codice;
    printf("inserisci il codice del libro da rimuovere: ");
    scanf("%d", &codice);
    rimuovi_lista(codice);
}

int menu(){
    int k;
    printf("\n\t|1.inserire libro.|\n");
    printf("\t|2.rimuovere libro.|\n");
    printf("\t|3.visualizza libro con almeno una parola chiave uguale.|\n");
    printf("\t|4.visualizza libro con 3 parole chiave uguali.|\n");
    printf("\t|5.termina|\n\n");
	scanf("%d", &k);
    switch(k){
        case 1:
            inserisci();
            menu();
            break;
        case 2:
            rimuovi();
            menu();
            break;
        case 3:
            visualizza1();
            menu();
            break;
         case 4:
         	visualizza3();
         	menu();
         	break;
        case 5:
        	default:
            break;
    }
}

void salva(){
	FILE *file = fopen("save.txt","w");  //qui salvo il file in scrittura
	nodo *p;
	for(p=dati.lista; p!=NULL; p=p->next){                            
	    fprintf(file, "%d %s %s %s %s %s %s %s\n", p->ele->codice, p->ele->autore, p->ele->titolo, p->ele->chiave[0], p->ele->chiave[1], p->ele->chiave[2], p->ele->chiave[3], p->ele->chiave[4]);
	}
	fclose(file); 
}

void carica(){
	FILE *file;
	dati_libro *ele;         
	int esito;
    dati.lista = NULL;
    file = fopen("save.txt","r");
	if(file == NULL)
	    return;
	while(1){                            
        ele = malloc(sizeof(dati_libro));
	    esito = fscanf(file, "%d %s %s %s %s %s %s %s\n", &ele->codice, ele->autore, ele->titolo, ele->chiave[0], ele->chiave[1], ele->chiave[2], ele->chiave[3], ele->chiave[4]);
	    if(esito == EOF)
	        break;
        inserisci_testa(&dati.lista, ele);
	}
	fclose(file); 
}

int main(){          
    carica();
    menu();
    salva();
    return 0;
} 
questo programma dovrebbe rappresentare una libreria, dove tramite il menu vengono inseriti e vari libri abbinando loro delle parole chiave per poter permettere la ricerca in un secondo momento. basta che lo avviate e capirete subito quello che fa. comunque devo sistemarlo poichè nel momento in cui mi chiede di inserire il nome dell'autore o del titolo posso scrivere solamente una parola, poichè utilizzo soltanto una scanf. e poi magari anche evitare che nel menù se l'utente inserisce una lettera dell'alfabeto il programma non termini così ma dica all'utente di inserire un numero.
L'ideale sarebbe che il programma possa ricevere questi dati all'interno:
Codice: 123456

Autore: Dan Brawn

Titolo: Il codice Da Vinci

Parole chiave: thriller romanzo massoneria bestseller 2003.

ps: anche una dritta su come fare una funzione che visualizzi tutti i libri presenti in libreria senza l'inserimento di parole chiavi. vi ringrazio in anticipo e spero di essere stato abbastanza chiaro.

16 Risposte

  • Re: Libreria in C

    Scusa ma non ho capito il problema da affrontare.

    La domanda qual è ?
  • Re: Libreria in C

    Controlla adesso la funzione menu() e vedi se va meglio
    
    int menu()
    {
    	int k = 0;
    	int result = 0;
    	char svuota[100];
    	do
    	{
    		printf("\n\t|1.inserire libro.|\n");
    		printf("\t|2.rimuovere libro.|\n");
    		printf("\t|3.visualizza libro con almeno una parola chiave uguale.|\n");
    		printf("\t|4.visualizza libro con 3 parole chiave uguali.|\n");
    		printf("\t|5.termina|\n\n");
    		result = scanf("%d", &k);
    		if(result != 1)
    		{
    			printf("Input non corretto, riprova!!!!\n\n");
    			scanf("%s",svuota);
    			continue;
    		}
    		switch(k)
    		{
    			case 1:
    				inserisci();
    			break;
    			case 2:
    				rimuovi();
    			break;
    			case 3:
    				visualizza1();
    			break;
    			case 4:
    				visualizza3();
    			break;
    			case 5:
    			break;
    		}
    	}while(k < 1 || k > 5);
    	return k;
    }
    
    Per il resto vediamo dopo.

    Edit: cambia il while così
    
    while(k != 5);
    
  • Re: Libreria in C

    Versione migliore
    
    int menu()
    {
    	int k = 0;
    	int result = 0;
    	char svuota[100];
    	do
    	{
    		printf("\n\t|1.inserire libro.|\n");
    		printf("\t|2.rimuovere libro.|\n");
    		printf("\t|3.visualizza libro con almeno una parola chiave uguale.|\n");
    		printf("\t|4.visualizza libro con 3 parole chiave uguali.|\n");
    		printf("\t|5.termina|\n\n");
    		result = scanf("%d", &k);
    		if(result != 1)
    		{
    			printf("Input non corretto (si  accettano solo numeri), riprova!!!!\n\n");
    			scanf("%s",svuota);
    			continue;
    		}
    		switch(k)
    		{
    			case 1:
    				inserisci();
    			break;
    			case 2:
    				rimuovi();
    			break;
    			case 3:
    				visualizza1();
    			break;
    			case 4:
    				visualizza3();
    			break;
    			case 5:
    			break;
    			default:
    			{
    				printf("Input non corretto, inserire numeri da 1 a 5, riprova!!!!\n\n");
    			}
    			break;
    		}
    	}while(k != 5);
    	return k;
    }
    
  • Re: Libreria in C

    Grazie skynet per l'aiuto sul menù adesso non da alcun problema:) anche se non ho ben capito come funziona, quindi ti chiedo qualche chiarimento per favore.

    mentre il problema principale adesso rimangono le scanf per l'inserimento di autore e titolo del libro che non mi permettono di inserire sia più di una parola. se mi potreste aiutare anche in questo sareste davvero gentili.

    grazie ancora dell'aiuto.
  • Re: Libreria in C

    Quindi il problema è l'input di più parole con la scanf ?

    Lasciala stare e usa la fgets

    fgets(stringa, maxlen, stdin);
  • Re: Libreria in C

    Si anch'io avevo pensato alla fgets ma sinceramente non capisco come scriverla.
  • Re: Libreria in C

    Salve ho inserito anche una funzione che mi permetta di vedere tutti i dati all'interno della libreria senza l'inserimento di parole chiave con questa funzione:
    void visualizza_tutto(){   //funzione per visualizzare l'intera libreria 
    
        nodo *p;
    	
    	for(p=dati.lista; p!=NULL; p=p->next){
    	 		    stampa(p->ele);
    		    }         
            }
    penso sia giusta, comunque adesso l'unico problema rimangoono le scnaf che mi permettono di inserire soltanto una parola come autore o titolo. mi servirebbe un aiuto per impostare una fgets che mi legga una stringa per favore. grazie
  • Re: Libreria in C

    Puoi usare l'aiuto dato da oregon. Credo che non ci sia altro da aggiungere.
  • Re: Libreria in C

    Va bene grazie ancora
  • Re: Libreria in C

    #include<stdio.h>
    #include<string.h>
    #define max 500
    
    typedef struct dati_libro{
        int codice;
        char autore[20];
        char titolo[20];
        char chiave[5][50];
    }dati_libro;
    
    typedef struct nodo{
        dati_libro *ele;
    	struct nodo *next;
    }nodo;        
    
    typedef struct biblioteca{
        nodo *lista;
    }biblioteca;
            
    void inserisci_testa(nodo **testa, dati_libro *libro){
    	nodo *new = malloc(sizeof(nodo)); //creazione del nuovo nodo
    	new->ele = libro;
    	new->next = *testa;               //aggancio in testa
    	*testa = new;                     //aggiornamento del puntatore alla testa
    }
    	 
    biblioteca dati;                                
    
    int inserisci_libro(){                               //funzione per inserire i dati del libro
    	int aggiungi, i;
    	char s[20];
      	dati_libro *libro = malloc(sizeof(dati_libro));
        printf("aggiungi dati libro\n");
        printf("inserire codice libro :\n");
    	scanf("%d", &libro->codice);
        printf("inserire autore:\n");
        fgets(s, 20, stdin);
    	*s = libro->autore;
        //scanf("%s", &libro->autore);
        printf("inserire titolo:\n");
        scanf("%s", &libro->titolo);
        printf("inserire 5 parole chiave\n");
        for(i=0;i<5;i++){                                                //ciclo for per inserire 5 parole chiavi per ogni libro inserito
      	    printf("inserire parola chiave numero %d:\n", i+1);
            scanf("%s", libro->chiave[i]);
            printf("hai inserito: %s\n", libro->chiave[i]);
        }
    	inserisci_testa(&dati.lista, libro);
        printf("se vuoi altri dati digita '1', se vuoi terminare digita '0'\n");
        scanf("%d", &aggiungi);
        return aggiungi;
    }
                    
    int inserisci(){
        int aggiungi;
        do{
    	    aggiungi = inserisci_libro();
        } while(aggiungi!=0);
    }
    ho provato seguendo il vostro consiglio ma mi salta proprio la riga e non riesco a capire dov'è l'errore.
  • Re: Libreria in C

    Devi pulire il buffer di input dopo la scanf prima della fgets. Quindi, subito dopo la scanf del codice, aggiungi la riga

    while(getchar() != '\n');
  • Re: Libreria in C

    Seguendo i vostri consigli sono riuscito a completare il programma più o meno, ieri avviandolo le prime volte sembrava girare bene ma dopo qualche tentativo nel momento in cui davo il comando da terminale per avviarlo mi si bloccava un pò tutto il pc. vi posto un'immagine dell'avvio del programma:
    e per sbloccare il tutto devo terminare il programma con ctrl+z.

    posto anche il programma completo, spero mi possiate aiutare.
    #include<stdio.h>
    #include<string.h>
    #define max 500
    
    typedef struct dati_libro{
        int codice;
        char autore[20];
        char titolo[20];
        char chiave[5][50];
    }dati_libro;
    
    typedef struct nodo{
        dati_libro *ele;
    	struct nodo *next;
    }nodo;        
    
    typedef struct biblioteca{
        nodo *lista;
    }biblioteca;
            
    void inserisci_testa(nodo **testa, dati_libro *libro){
    	nodo *new = malloc(sizeof(nodo)); //creazione del nuovo nodo
    	new->ele = libro;
    	new->next = *testa;               //aggancio in testa
    	*testa = new;                     //aggiornamento del puntatore alla testa
    }
    	 
    biblioteca dati;                                
    
    int inserisci_libro(){                               //funzione per inserire i dati del libro
    	int aggiungi, i;
    	
      	dati_libro *libro = malloc(sizeof(dati_libro));
        printf("aggiungi dati libro\n");
        printf("inserire codice libro :\n");
    	scanf("%d", &libro->codice);
        printf("inserire autore:");
        while(getchar() != '\n');
        fgets(libro->autore, 20, stdin);
        printf("inserire titolo:\n");
        fgets(libro->titolo, 20, stdin);
        
        printf("inserire 5 parole chiave\n");
        for(i=0;i<5;i++){                                                //ciclo for per inserire 5 parole chiavi per ogni libro inserito
      	    printf("inserire parola chiave numero %d:\n", i+1);
            scanf("%s", libro->chiave[i]);
            printf("hai inserito: %s\n", libro->chiave[i]);
        }
    	inserisci_testa(&dati.lista, libro);
        printf("se vuoi altri dati digita '1', se vuoi terminare digita '0'\n");
        scanf("%d", &aggiungi);
        return aggiungi;
    }
                    
    int inserisci(){
        int aggiungi;
        do{
    	    aggiungi = inserisci_libro();
        } while(aggiungi!=0);
    }
    
    void stampa(dati_libro *libro){                      
        printf("codice del libro e': %d\n", libro->codice);
    	printf("il titolo del libro e': %s\n", libro->titolo);
    	printf("l'autore e': %s\n", libro->autore);
    	printf("\n");
    }
    
    void visualizza3(){
     	char parola[3][20];
        int a, b, c;
        int count;
        nodo *p;
    	printf("per visualizzare il libro cercato inserire 3 parole chiave\n");
        for(a=0;a<3;a++){
            printf("inserire la %d parola chiave\n", a+1);
    	    scanf("%s", parola[a]);
        }
    	for(p=dati.lista; p!=NULL; p=p->next){ //scorro la lista
    	    count=0;
            for(b=0; b<3; b++) //ogni parola chiave cercata
                for(c=0; c<5; c++) //viene confrontata con le 5 parole chiave del libro
                //se la parola corrisponde incremento count e passo alla prossima parola chiave da cercare
                    if(strcmp(parola[b], p->ele->chiave[c]) == 0){ 
    	                count++; 
    	                break;
    	            }
            if(count==3) //tutte e tre le parole sono state trovate
                stampa(p->ele);
    	 }
    }
    
    
    void visualizza1(){   //funzione per inserire 3 parole chiavi per cercare il libro 
     	char parola[3][20];
        int a, b, c;
        int count;
        nodo *p;
    	printf("per visualizzare il libro cercato inserire 3 parole chiave\n");
    	for(a=0;a<3;a++){
            printf("inserire la %d parola chiave\n", a+1);
    	    scanf("%s", parola[a]);
    	}
    	for(p=dati.lista; p!=NULL; p=p->next){
    	    count=0;
            for(b=0; b<3; b++){
                for(c=0; c<5; c++){
                    if(strcmp(parola[b], p->ele->chiave[c])==0){
    			  //se una parola corrisponde metto count = 1 e termino il for interno
    	                count=1;
    				    break;
                    }
    	        }
    		    if(count == 1){
    		 		  //se count == 1 stampo i dati e termino il for intermedio
    	 		    stampa(p->ele);
    		        break;
    		    }         
            }
        }
    }
    
    void visualizza_tutto(){   //funzione per visualizzare l'intera libreria 
    
        nodo *p;
    	
    	for(p=dati.lista; p!=NULL; p=p->next){
    	 		    stampa(p->ele);
    		    }       
            }
    	
    
    
    void rimuovi_lista(int codice){ //funzione per rimuovere il libro
    	nodo *p, *q = NULL;
    	for(p=dati.lista; p!=NULL && p->ele->codice != codice; p=p->next)
    	    q = p;
        if(p == NULL) //se il libro non è presente nella biblioteca stampo:"..."
            printf("il libro non e' presente nella biblioteca\n");
        else{       //nel caso in cui trovo il libro nella biblioteca tramite la funzione "free" rimuovo il libro dalla biblioteca
            if(q == NULL)
                dati.lista = p->next;
            else
    		    q->next = p->next;
    		free(p);
    		printf("libro #%d rimosso con successo\n", codice);
    	}
    }
    
    void rimuovi(){
        int codice;
        printf("inserisci il codice del libro da rimuovere: ");
        scanf("%d", &codice);
        rimuovi_lista(codice);
    }
    
    int menu()
    {
       int k = 0;
       int result = 0;
       char svuota[100];
       do
       {
          printf("\n\t|1.inserire libro.|\n");
          printf("\t|2.rimuovere libro.|\n");
          printf("\t|3.visualizza libro con almeno una parola chiave uguale.|\n");
          printf("\t|4.visualizza libro con 3 parole chiave uguali.|\n");
    	  printf("\t|5.visualizza tutta la libreria.|\n"); 
          printf("\t|6.termina|\n\n");
          result = scanf("%d", &k);
          if(result != 1)
          {
             printf("Input non corretto (si  accettano solo numeri), riprova!!!!\n\n");
             scanf("%s",svuota);
             continue;
          }
          switch(k)
          {
             case 1:
                inserisci();
             break;
             case 2:
                rimuovi();
             break;
             case 3:
                visualizza1();
             break;
             case 4:
                visualizza3();
             break;
             case 5:
             	visualizza_tutto();
             	menu();
             break;
             case 6:
             	break;
             	default:
             {
                printf("Input non corretto, inserire numeri da 1 a 6, riprova.\n\n");
             }
             break;
          }
       }while(k != 6);
       return k;
    }
    
    void salva(){
    	FILE *file = fopen("save.txt","w");  //qui salvo il file in scrittura
    	nodo *p;
    	for(p=dati.lista; p!=NULL; p=p->next){                            
    	    fprintf(file, "%d %s %s %s %s %s %s %s\n", p->ele->codice, p->ele->autore, p->ele->titolo, p->ele->chiave[0], p->ele->chiave[1], p->ele->chiave[2], p->ele->chiave[3], p->ele->chiave[4]);
    	}
    	fclose(file); 
    }
    
    void carica(){
    	FILE *file;
    	dati_libro *ele;         
    	int esito;
        dati.lista = NULL;
        file = fopen("save.txt","r");
    	if(file == NULL)
    	    return;
    	while(1){                            
            ele = malloc(sizeof(dati_libro));
    	    esito = fscanf(file, "%d %s %s %s %s %s %s %s\n", &ele->codice, ele->autore, ele->titolo, ele->chiave[0], ele->chiave[1], ele->chiave[2], ele->chiave[3], ele->chiave[4]);
    	    if(esito == EOF)
    	        break;
            inserisci_testa(&dati.lista, ele);
    	}
    	fclose(file); 
    }
    
    int main(){          
        carica();
        menu();
        salva();
        return 0;
    } 
    grazie in anticipo.
  • Re: Libreria in C

    Prova ad aggiungere, subito prima della scanf del menu, una linea

    fflush(stdout);
  • Re: Libreria in C

    Il buffer sembra essere già pieno dato che non mi il programma non mi si avvia, c'è un modo per svuotarlo prima dell'avvio del programma?
    comunque l'ho posizionato qua, spero sia giusto:
      printf("\t|6.termina|\n\n");
          fflush(stdout);
          result = scanf("%d", &k);
          if(result != 1)
          {
             printf("Input non corretto (si  accettano solo numeri), riprova!!!!\n\n");
             scanf("%s",svuota);
             continue;
          }
Devi accedere o registrarti per scrivere nel forum
16 risposte