RISOLTO [C] Esercizio gestione biblioteca

Stato
Discussione chiusa ad ulteriori risposte.

sare1234

Utente Attivo
262
3
buonasera volevo chiedere se qualcuno mi aiuta devo gestire una biblioteca ma l'operazione di prestito e richiesta di un libro non mi funzionano...vi prego è un progetto e tra pochi giorni devo consegnarlo
grazie in anticipo.
Codice:
#include <stdio.h>


#include <stdlib.h>
#include <string.h>
#define MAXLEN 100

typedef struct {
char nome;
char cognome;
char matricola;
struct Studente *next;
}Studente;

typedef struct {
Studente element[100];
int num_studente;
}List;


struct libri{
  char titolo[100];
   char autore[100];
  int cod_id;
struct libri *next;
};
typedef struct {
  struct libri elementi[100];
   int num_libri;
}Libro;

List Inserimento_Studente();
int Cerca_Titolo(struct libri list ,char titolo, char autore);
struct libri initList(char titolo,char autore,int cod_id);
struct libri insertHead(struct libri L, char titolo,char autore, int cod_id);
//struct libri *CREA_LISTA(struct libri *TOP);
int menu();
libri *leggiFile(FILE *fp, libri *lista);
void scriviLista(struct libri *lista);
void scriviFile(FILE *fp, struct libri *lista);
static struct libri *nuovoNodo(char *titolo,char *autore, int cod_id);
static void freeNodo(struct libri *nodo);
void gestioneErrore();
void freeLista(struct libri *lista);
void stampaLista(struct libri *top);

int main() {
int scelta;
FILE *fp;
struct persona *lista=NULL;
struct lista *top = NULL;
int cod_id;
char titolo;
char autore;
struct libri L;
int presenza;
Libro l;
//lista = nuovoNodo(titolo,autore,cod_id);
//CREA_LISTA(lista);
//lista = inserisciLista(L,autore);

while((scelta = menu())){
switch (scelta) /* Creo uno switch con 5 case, uno per ogni possibile scelta */
{
case 1: /*stampa lista*/
      fp = fopen("Libri.txt","r");
if (fp == NULL) gestioneErrore();
        lista = leggiFile(fp, lista);
        fclose(fp);
       lista= scriviLista(lista);
        //stampaLista(top);
        break;


case 2: /* Se l'utente preme il tasto dove il libro viene cercato e se è presente lo studente deve inserire matricola cognome e nome

printf("\nInserisci titolo libro da richiedere:");
        fflush(stdin);
      gets(titolo);
    fp = fopen("Libri.txt","r");
     lista = leggiFile(fp, lista);
     fclose(fp);
presenza = Cerca_Titolo(l,titolo);
      if(titolo != -1) {
printf("Il libro cercato  e' presente nell'archivio ed il libro  e' disponibile\n");
     Inserimento_Studente();
         } else {
printf("Il libro cercato non e' presente nell'archivio ed il libro non e' disponibile\n");

     }
    fclose(fp);
   break;
case 3: /* Case costruito per restituire un libro tramite codice*/
  break;

case 4: /*esegui richiesta*/
  break ;

case 5: /*Se l'utente vuole uscire dalla biblioteca*/
printf("Grazie per aver scelto il servizio di gestione della biblioteca, torna a trovarci!\n");
      break;

default: /*Se l'utente sbaglia ad inserire il numero*/
       printf("Questo tasto non consente di effetuare scelte! Riprova!\n");

        break;
     } /*Fine switch*/

   } /*Fine do*/
   return scelta;

} /*Fine main*/

int menu(){
int scelta; /*Questa variabile sarà utilizzata nella switch per decidere che cosa fare...*/
  printf("* * * * * * * * * * * * * * * * * * *  \nBenvenuto nel programma di gestione biblioteca\n* * * * * * * * * * * * * * * * * * *  \n");

   printf(" 1. Mostra archivio\n");
    printf(" 2. Richiedi libro\n");
printf(" 3. Restituire libro\n");
printf(" 4. Esegui richiesta\n");
   printf(" 5. Uscire\n");
    printf("Inserisci scelta:");
scanf("%d",&scelta); /*Viene inserito nella variabile var il numero inserito dall'utente e di conseguenza inserito nel ciclo Switch*/
while(scelta<0 || scelta>5) {     printf("Questo tasto non consente di effetuare scelte! Riprova!\n");
     printf("Scelta: ");
     scanf("%d", &scelta);
     return scelta;
}

  return scelta;
}


static struct libri *nuovoNodo(char *titolo,char *autore, int cod_id)
{

  struct libri *nodo;
nodo = (struct libri *) malloc(sizeof(struct libri));
if (nodo == NULL) return NULL;
  strcpy(nodo->titolo,titolo);
  strcpy(nodo->autore, autore);
  nodo->cod_id =cod_id;
  nodo->next = NULL;
  return nodo;
}

static void freeNodo(struct libri *nodo)
{

  free((void *) nodo);

}

static struct libri *inserisciLista(struct libri *nodo, struct libri *lista)
{

  if (lista==NULL) return nodo;
lista->next = inserisciLista(nodo, lista->next);
  return lista;
}

void gestioneErrore()
{
printf("Errore\n");
  exit(0);

}

void freeLista(struct libri *lista)
{
  if (lista != NULL) {
   freeLista(lista->next);
   freeNodo(lista);

  }

}

void scriviLista(struct libri *lista)

{

  while (lista!=NULL) {
    printf("%s %s %d\n",lista->titolo,lista->autore,lista->cod_id);
    lista = lista->next;
  }

  printf("\n");

}

libri *leggiFile(FILE *fp,  libri *lista)
{
  char titolo[256], autore[256];
  int cod_id;
  struct libri *nodo;
while(fscanf(fp,"%s%s%d",titolo,autore,&cod_id)==3){
    nodo = nuovoNodo(titolo,autore,cod_id);
   if (nodo == NULL)
       gestioneErrore();

    lista = inserisciLista(nodo, lista);
  }
  return lista;

}

void scriviFile(FILE *fp, struct libri *lista)
{
  while (lista!=NULL) {
   fprintf(fp,"%s %s %d \n",lista->titolo,lista->autore,lista->cod_id);
  lista = lista->next;

  }

}
void stampaLista(struct libri *top)

{
   if (top == NULL) {
      printf("\n--------------\n\n");
   }else

       if (top!=NULL && top->titolo!=0) {
  printf("%s %s %d", top->titolo,  top->autore, &top->cod_id);
    stampaLista(top->next);

    }
}


//struct libri *CREA_LISTA(struct libri *TOP){
//struct libri *tmp=(struct libri*)malloc(sizeof(struct libri));
//tmp->next=TOP;
//strcpy(tmp->titolo,TOP->titolo);
//strcpy(tmp->autore,TOP->autore);
//tmp->cod_id=TOP->cod_id;
//return tmp;
//}

int Cerca_Titolo(Libro list ,char titolo){
int j;
int presenza=-1;
  for(j=0; j<list.num_libri; j++) {
       if(strcmp(list.elementi[j].titolo, &titolo)==0){
        presenza=1;
   }
}
return presenza;
}

List Inserimento_Studente(){
  List lista;
  int i;
printf("\n Quanti libri vuoi prendere in prestito? :");
scanf("%d",&lista.num_studente);
fflush(stdin);
for(i=0; i <lista.num_studente; i++) {
   printf("\nInserisci nome: ");
  gets(&lista.element[i].nome);
   printf("\nInserisci cognome: ");
   gets(&lista.element[i].cognome);
   printf("\nInserisci matricola: ");
   scanf("%s", &lista.element[i].matricola);
  fflush(stdin);
  }
   return lista;
}
Post unito automaticamente:

ho 15 libri priori che metto nel file
 
Ultima modifica:

BAT

Moderatore
Staff Forum
Utente Èlite
22,655
11,440
CPU
1-Neurone
Dissipatore
Ventaglio
RAM
Scarsa
Net
Segnali di fumo
OS
Windows 10000 BUG
Se vuoi che qualcuno ti aiuti, ti suggerisco di riformattare il codice togliendo le righe bianche inutili, inserito in questo modo è illeggibile.
 

fabio93

Utente Attivo
609
173
CPU
AMD Ryzen 5 2400G
Dissipatore
Arctic Alpine64 Plus
Scheda Madre
Gigabyte GA-AX370-Gaming 3
HDD
Crucial MX500 250 GB, Crucial BX500 240 GB
RAM
G.Skill F4-3200C14D-16GFX FlareX 16 GB
Monitor
HP 2010i
PSU
Corsair TX550M
Case
Sharkoon M25-W
Periferiche
Magicforce 68, Logitech G203
OS
Windows 10 Pro, Fedora 31
Quando tenti di compilare vedrai che il compilatore segnala degli errori di sintassi dovuti a discordanza di tipo tra parametri.
Hai dichiarato la funzione leggiFile() come struct libri *leggiFile(FILE *fp, struct libri *lista);, ma alla riga 68 la chiami con lista = leggiFile(fp, lista); e lista è di tipo puntatore a struct persona.
Analogamente alla riga 70 per la chiamata a scriviLista().
Poi, il prototipo della funzione Cerca_Titolo: int Cerca_Titolo(struct libri list ,char titolo); differisce per un parametro di input dalla definizione della medesima int Cerca_Titolo(Libro list ,char titolo)
Non so che IDE usi ma dovresti vederli.

Non ho guardato bene il codice ma a una prima occhiata noto altri errori:
gets(titolo) alla riga 79 con titolo dichiarato come variabile char mentre gets() si aspetta un puntatore a char/array di char. Nella printf("%s %s %d", top->titolo, top->autore, &top->cod_id); alla riga 226, con &top->cod_id stai passando un puntatore a puntatore a integer, dovevi usare top->cod_id (oppure (*top).cod_id).
Infine nelle gets e scanf nella funzione Inserimento_Studente(), dato che leggi delle stringhe, non serve mettere '&' davanti all'array di destinazione, perché in C il nome di un array coincide con l'indirizzo del suo primo elemento, quindi, ad esempio, se hai un array char nome[10];, nome corrisponde a &nome[0]
 
Ultima modifica:

sare1234

Utente Attivo
262
3
Bha a me compilava....comunque ho modificato
Post unito automaticamente:

Bha a me compilava....comunque ho modificato....so che magari non si può ma puoi aiutarmi tra qualche giorno devo consegnare il codice è non so come fare
Post unito automaticamente:

Quando tenti di compilare vedrai che il compilatore segnala degli errori di sintassi dovuti a discordanza di tipo tra parametri.
Hai dichiarato la funzione leggiFile() come struct libri *leggiFile(FILE *fp, struct libri *lista);, ma alla riga 68 la chiami con lista = leggiFile(fp, lista); e lista è di tipo puntatore a struct persona.
Analogamente alla riga 70 per la chiamata a scriviLista().
Poi, il prototipo della funzione Cerca_Titolo: int Cerca_Titolo(struct libri list ,char titolo); differisce per un parametro di input dalla definizione della medesima int Cerca_Titolo(Libro list ,char titolo)
Non so che IDE usi ma dovresti vederli.

Non ho guardato bene il codice ma a una prima occhiata noto altri errori:
gets(titolo) alla riga 79 con titolo dichiarato come variabile char mentre gets() si aspetta un puntatore a char/array di char. Nella printf("%s %s %d", top->titolo, top->autore, &top->cod_id); alla riga 226, con &top->cod_id stai passando un puntatore a puntatore a integer, dovevi usare top->cod_id (oppure (*top).cod_id).
Infine nelle gets e scanf nella funzione Inserimento_Studente(), dato che leggi delle stringhe, non serve mettere '&' davanti all'array di destinazione, perché in C il nome di un array "coincide" con un puntatore al suo primo elemento, quindi, ad esempio, se hai un array char nome[10];, nome corrisponde a &nome[0]
Allora domani li correggo e rimando il codice così è più chiaro
 
Ultima modifica:

fabio93

Utente Attivo
609
173
CPU
AMD Ryzen 5 2400G
Dissipatore
Arctic Alpine64 Plus
Scheda Madre
Gigabyte GA-AX370-Gaming 3
HDD
Crucial MX500 250 GB, Crucial BX500 240 GB
RAM
G.Skill F4-3200C14D-16GFX FlareX 16 GB
Monitor
HP 2010i
PSU
Corsair TX550M
Case
Sharkoon M25-W
Periferiche
Magicforce 68, Logitech G203
OS
Windows 10 Pro, Fedora 31
Il compilatore dev'essere il tuo migliore amico. Ad esempio se usi gcc ti basta usare gcc -o nome_eseguibile nome_sorgente.c per compilare e avere i principali warning, se poi aggiungi l'opzione -Wall ne hai di più, e ti avvisa non solo di errori di sintassi che impediscono la compilazione, ma anche, ad esempio, di variabili dichiarate ma non usate, e altri problemi minori.
 

sare1234

Utente Attivo
262
3
ho aggiustato un po di cose
Codice:
#include <stdio.h>


#include <stdlib.h>


#include <string.h>


#define MAXLEN 100





struct libri{


    char titolo[100];


    char autore[100];


    int cod_id;


    struct libri *next;


};





typedef struct {


    struct libri elementi[100];


   int num_libri;


}Libro;


void ricerca (struct libri **l, int num_l) ;


//int Cerca_Titolo(Libro list ,char titolo);


struct libri initList(char titolo,char autore,int cod_id);


struct libri insertHead(struct libri L, char titolo,char autore, int cod_id);


//struct libri *CREA_LISTA(struct libri *TOP);


int menu();


struct libri *leggiFile(FILE *fp, struct libri *lista);


void scriviLista(struct libri *lista);


void scriviFile(FILE *fp, struct libri *lista);


static struct libri *inserisciLista(struct libri *nodo, struct libri *lista);


static struct libri *nuovoNodo(char *titolo,char *autore, int cod_id);


static void freeNodo(struct libri *nodo);


void gestioneErrore();


void freeLista(struct libri *lista);


void stampaLista(struct libri *top);





int main() {


    int scelta;


    FILE *fp;


    struct libri *lista=NULL;


    struct lista *top = NULL;


    int cod_id;


    char titolo;


    char autore;


    struct libri L;


    int presenza;


    Libro l;


    int nu = 0;


    


    fp = fopen("Libri.txt","r");


           if (fp == NULL) gestioneErrore();


           lista = leggiFile(fp, lista);


           fclose(fp);


//lista = nuovoNodo(titolo,autore,cod_id);


//CREA_LISTA(lista);


//lista = inserisciLista(L,autore);





while((scelta = menu())){


switch (scelta) /* Creo uno switch con 5 case, uno per ogni possibile scelta */





{


 case 1: /*stampa lista*/





        //fp = fopen("Libri.txt","r");


        //if (fp == NULL) gestioneErrore();


        //lista = leggiFile(fp, lista);


       // fclose(fp);


        scriviLista(lista);


        //stampaLista(top);


    break;





    case 2: /* Se l'utente preme il tasto 2 si cerca se c'e il libro e richiedere un libro tramite il codice*/


        


           ricerca(&l,nu);


        


    break;





case 3: /* Case costruito per restituire un libro tramite codice*/








       








        break;








        








case 4: /*esegui richiesta*/








        break ;








case 5: /*Se l'utente vuole uscire dalla biblioteca*/








printf("Grazie per aver scelto il servizio di gestione della biblioteca, torna a trovarci!\n");








        break;

















default: /*Se l'utente sbaglia ad inserire il numero*/








        printf("Questo tasto non consente di effetuare scelte! Riprova!\n");








        break;

















      } /*Fine switch*/








   } /*Fine do*/








    return scelta;








} /*Fine main*/





int menu(){


int scelta; /*Questa variabile sarà utilizzata nella switch per decidere che cosa fare...*/


    printf("* * * * * * * * * * * * * * * * * * *  \nBenvenuto nel programma di gestione biblioteca\n* * * * * * * * * * * * * * * * * * *  \n");


    





    printf(" 1. Mostra archivio\n");


    printf(" 2. Richiedi libro\n");


    printf(" 3. Restituire libro\n");


    printf(" 4. Esegui richiesta\n");


    printf(" 5. Uscire\n");


    printf("Inserisci scelta:");


    scanf("%d",&scelta); /*Viene inserito nella variabile var il numero inserito dall'utente e di conseguenza inserito nel ciclo Switch*/


    while(scelta<0 || scelta>5) {     printf("Questo tasto non consente di effetuare scelte! Riprova!\n");


        printf("Scelta: ");


        scanf("%d", &scelta);


      return scelta;


 }


  return scelta;


}


static struct libri *nuovoNodo(char *titolo,char *autore, int cod_id)


{


  struct libri *nodo;





  nodo = (struct libri *) malloc(sizeof(struct libri));


  if (nodo == NULL) return NULL;


  strcpy(nodo->titolo,titolo);


  strcpy(nodo->autore, autore);


  nodo->cod_id =cod_id;


  nodo->next = NULL;


    


  return nodo;


}





static void freeNodo(struct libri *nodo)


{


  free((void *) nodo);


}





static struct libri *inserisciLista(struct libri *nodo, struct libri *lista)


{


  if (lista==NULL) return nodo;


  lista->next = inserisciLista(nodo, lista->next);


  return lista;


}








void gestioneErrore()


{


  printf("Errore\n");





  exit(0);


}





void freeLista(struct libri *lista)


{


  if (lista != NULL) {


    freeLista(lista->next);


    freeNodo(lista);


  }


}








void scriviLista(struct libri *lista)


{


  while (lista!=NULL) {


    printf("%s %s %d\n",lista->titolo,lista->autore,lista->cod_id);


    lista = lista->next;


  }


  printf("\n");


}





struct libri *leggiFile(FILE *fp, struct libri *lista)


{


  char titolo[256], autore[256];


  int cod_id;


  struct libri *nodo;





  while(fscanf(fp,"%s%s%d",titolo,autore,&cod_id)==3){


    nodo = nuovoNodo(titolo,autore,cod_id);


    if (nodo == NULL)


        gestioneErrore();


    lista = inserisciLista(nodo, lista);


  }


  return lista;


}





void scriviFile(FILE *fp, struct libri *lista)


{


  while (lista!=NULL) {


    fprintf(fp,"%s %s %d \n",lista->titolo,lista->autore,lista->cod_id);


    lista = lista->next;


  }


}





void stampaLista(struct libri *top)


{


    if (top == NULL) {


        printf("\n--------------\n\n");


    }else


       if (top!=NULL && top->titolo!=0) {


printf("%s %s %d", top->titolo,  top->autore, &top->cod_id);


    stampaLista(top->next);





    }





}


//struct libri *CREA_LISTA(struct libri *TOP){


//struct libri *tmp=(struct libri*)malloc(sizeof(struct libri));


//tmp->next=TOP;


//strcpy(tmp->titolo,TOP->titolo);


//strcpy(tmp->autore,TOP->autore);


//tmp->cod_id=TOP->cod_id;


//return tmp;


//}





//int Cerca_Titolo(Libro list ,char titolo){


//int j;


//int presenza=-1;


//  for(j=0; j<list.num_libri; j++) {


//      if(strcmp(list.elementi[j].titolo, &titolo)==0){


 //         presenza=1;


 // }


//}





// return presenza;





//}





void ricerca (struct libri ** l, int num_l) {


    int i,trovato = 0;


    char titolo[25];


    


    printf("\nInserirsci titolo da cercare: ");


    scanf("%s", titolo);


    getchar();


    for(i=0; i<num_l; i++) {


        if(strcmp(((*l)+i )->titolo, titolo)==0) {


            printf("\n Libro trovato");


            trovato=1;


        }


    }


    if(trovato != 1)


        printf("\n Libro non trovato");


}
ho modificato qualcosa ma al di la di questo vorrei capire come mai la richiesta del libro non mi funziona
 
Ultima modifica:

fabio93

Utente Attivo
609
173
CPU
AMD Ryzen 5 2400G
Dissipatore
Arctic Alpine64 Plus
Scheda Madre
Gigabyte GA-AX370-Gaming 3
HDD
Crucial MX500 250 GB, Crucial BX500 240 GB
RAM
G.Skill F4-3200C14D-16GFX FlareX 16 GB
Monitor
HP 2010i
PSU
Corsair TX550M
Case
Sharkoon M25-W
Periferiche
Magicforce 68, Logitech G203
OS
Windows 10 Pro, Fedora 31
Ciao, il prototipo della funzione ricerca è void ricerca (struct libri **l, int num_l);, ma alla chiamata ricerca(&l,nu); le passi l'indirizzo di "l" che è di tipo Libro. Ad ogni modo, gli errori di questo tipo sono segnalati dal compilatore, per cui facilmente individuabili. Che compilatore usi? Mi pare strano che ti faccia compilare lo stesso e non ti avvisi degli errori di sintassi.

P.S.: il return scelta; nel main non va bene. La funzione main deve restituire sempre 0 in caso di terminazione normale (si può usare anche la costante EXIT_SUCCESS).
Invece in gestioneErrore(), a parte che non spieghi qual è l'errore, chiami exit(0) che causa la terminazione del programma con il codice 0 di terminazione normale. Avresti potuto usare 1 per indicare una terminazione dovuta a un errore. Non sto dicendo che sia sbagliato, dipende da come vuoi implementare la gestione degli errori. Ad esempio, avresti potuto semplicemente far restituire NULL a leggiFile (anziché chiamare gestioneErrore) e gestire l'errore nel main, o chiamare gestioneErrore nel main come hai fatto per l'apertura del file.
Altra cosa, nei prototipi delle funzioni che non prendono argomenti in input sarebbe meglio scrivere void esplicitamente, altrimenti tu o un ipotetico programmatore utente del tuo codice potreste passare dei parametri e il codice verrebbe compilato lo stesso, il che potrebbe condurre a errori. E comunque per convenzione è bene specificare che la funzione non accetta parametri.
Codice:
#include <stdio.h>

void foo();

int main()
{
    int a = 6;
    foo(a); // viene compilato correttamente

    return 0;
}

void foo()
{
    printf("foo()\n");
}
 
Ultima modifica:

sare1234

Utente Attivo
262
3
utilizzo Xcode...in realtà ho risolto cosi e cerca il libro correttamente però se tipo voglio ritornare alla prima scelta i libri non vengono stampati e se tipo eseguo una ricerca indico nome e matricola poi se voglio fare un'altra ricerca non me la fa fare correttamente...come potrei risolvere?

In realtà funziona a momenti può essere un problema di compilatore?

mentre per il prestito dei libri come potrei fare?
 
Ultima modifica:

fabio93

Utente Attivo
609
173
CPU
AMD Ryzen 5 2400G
Dissipatore
Arctic Alpine64 Plus
Scheda Madre
Gigabyte GA-AX370-Gaming 3
HDD
Crucial MX500 250 GB, Crucial BX500 240 GB
RAM
G.Skill F4-3200C14D-16GFX FlareX 16 GB
Monitor
HP 2010i
PSU
Corsair TX550M
Case
Sharkoon M25-W
Periferiche
Magicforce 68, Logitech G203
OS
Windows 10 Pro, Fedora 31
Non ho esperienza con Xcode, ma mi sembra strano che ti faccia compilare del codice con errori sintattici. Da quel che ho letto Xcode utilizza Clang come compilatore per il C, e se provi a compilare il tuo codice con questo tool online, vedrai che ti dà gli stessi errori che ti ho evidenziato prima. Quest'altro invece utilizza Gcc.
Potresti provare a seguire questa guida per attivare i warning in Xcode. Per il resto mi è un po' difficile aiutarti visto che non avendo il file.

Per quanto riguarda la ricerca, non capisco perché, a differenza delle funzioni per stampare la lista, hai deciso di passare un puntatore a puntatore a struct libri. Ti basta passare un puntatore a struct libri (cioè la lista), come per le altre funzioni, e vedrai che funziona. Non ho capito nemmeno la funzione del parametro 'num_l', così come non è molto logico l'uso di un for che scandisce la lista fino a questo valore. Non è un array, ti basta fare un while usando come condizione l != NULL && trovato != 1, in modo da uscire dal ciclo non appena il flag 'trovato' assume valore 1. Altrimenti, verrà scandita comunque tutta la lista.
Detto ciò, non so esattamente come debba essere formattato il file all'interno del quale fai la ricerca, ma, dato che nella realtà di solito i titoli dei libri e i nomi delle persone hanno degli spazi al loro interno, dovresti gestire il file e l'input in modo appropriato, ad esempio usando come separatore una virgola (o meglio un altro carattere che non può comparire all'interno dei nomi) e non lo spazio, e usando fgets invece di scanf, ad esempio.
Poi non funziona l'uscita dal programma, nel senso che quando digiti '5' il ciclo ricomincia, perché non hai posto come condizione che quando si digita '5' si esca.
 

sare1234

Utente Attivo
262
3
in realtà ho fatto cosi
Codice:
fp = fopen("Libri.txt","r");


      if (fp == NULL) gestioneErrore();


     printf("\nInserisci il titolo del libro:");


     scanf("%s", titoloricerca);


     fscanf(fp, "%s", titolofile);


     while (!feof(fp))


     {


      if (strcmp(titolofile,titoloricerca)==0){


        printf("\n Il libro cercato e' presente nell'archivio ed il libro e' disponibile %s!\n", titoloricerca);


          cont++;


         


          printf("Inserisci il nome: ");


          scanf("%s", &nome);


         


          printf("Inserisci il cognome: ");


          scanf("%s", &cognome);


         


          printf("Inserisci il matricola: ");


          scanf("%s", &matricola);


      }


        


      fscanf(fp, "%s", titoloricerca);


     }


     printf("Il libro cercato non e' presente nell'archivio ed il libro non e' disponibile\n");


  


        fclose(fp);

il file è quello
signore Redfield 34554
Potter Coelho 57777
La Bianchi 85345
Piccole Piero 60543
Guarnizione Napoleton 14532
nome Louise 10543
vento Jerry 35435
Odissea Bryne 40435
Cuore Marchesi 12534
Malavoglia Valeria 45433
Siddharta Still 245567
Lolita Wilcox 12534
Amabili Pone 35453
notre Boldi 15348
Possession Esposito 55435
 
Ultima modifica:

fabio93

Utente Attivo
609
173
CPU
AMD Ryzen 5 2400G
Dissipatore
Arctic Alpine64 Plus
Scheda Madre
Gigabyte GA-AX370-Gaming 3
HDD
Crucial MX500 250 GB, Crucial BX500 240 GB
RAM
G.Skill F4-3200C14D-16GFX FlareX 16 GB
Monitor
HP 2010i
PSU
Corsair TX550M
Case
Sharkoon M25-W
Periferiche
Magicforce 68, Logitech G203
OS
Windows 10 Pro, Fedora 31
Così è un po' difficile, dovresti postare il codice per intero, non solo un pezzo decontestualizzato dal resto del programma, e per favore, cerca di curare l'indentazione ed eliminare le righe vuote sennò diventa difficile leggere (e capire) il codice.
Comunque, deduco che questa sia una modifica della funzione di ricerca. Dato che hai già aperto il file nel main, perché lo riapri qui? Non ti serve. Se proprio volevi lavorare sul file, ti bastava passare il puntatore fp del main, che punta già al file (quindi non serve riaprirlo). Ma soprattutto, non serve lavorare sul file dato che hai già caricato il suo contenuto nella lista, quindi potevi fare benissimo la ricerca nella lista, come nel tuo tentativo precedente. Poi a che serve la variabile cont? E cosa sono cognome e matricola? E ti ripeto che nella scanf con gli array non serve mettere '&'. Inoltre, nel while hai messo fscanf(fp, "%s", titoloricerca);, mentre avrebbe dovuto essere fscanf(fp, "%s", titolofile); visto che stai leggendo una stringa dal file e memorizzandola nel vettore titolofile, non titoloricerca, che invece è la stringa da cercare nel file (cioè da confrontare con titoloricerca).
 

sare1234

Utente Attivo
262
3
siccome non riesco a mandarlo senza linea bianche lo allego
Codice:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXLEN 100
struct libri{
  char titolo[100];
 char autore[100];
 int cod_id;
struct libri *next;
};
typedef struct libri* List;
typedef struct {
    struct libri elementi[100];
  int num_libri;
}Libro;


int Cerca_Titolo(Libro list ,char titolo);
List initList(char titolo,char autore,int cod_id);
List insertTail(List L, char name[100], int age);
//struct libri *CREA_LISTA(struct libri *TOP);
int menu(void);
struct libri *leggiFile(FILE *fp, struct libri *lista);
void scriviLista(struct libri *lista);
void scriviFile(FILE *fp, struct libri *lista);
struct libri *nuovoNodo(char *titolo,char *autore, int cod_id);
void gestioneErrore(void);
void freeLista(struct libri *lista);
void stampaLista(struct libri *top);
int main() {
  int scelta;
FILE *fp;
 struct libri *lista=NULL;


    struct lista *top = NULL;


    int cod_id;


    char titolo;


    char autore;


    struct libri L;


    int presenza;


    Libro l;


    char titoloricerca[MAXLEN], titolofile[MAXLEN];


    int cont=0;


    char nome;


    char cognome;


    char matricola;


    int id;


    int n ;


   





//lista = nuovoNodo(titolo,autore,cod_id);


//CREA_LISTA(lista);


//lista = inserisciLista(L,autore);





while((scelta = menu())){


switch (scelta) /* Creo uno switch con 5 case, uno per ogni possibile scelta */





{


 case 1: /*stampa lista*/





       fp = fopen("Libri.txt","r");


        if (fp == NULL) gestioneErrore();


        lista = leggiFile(fp, lista);


        fclose(fp);


        scriviLista(lista);


        //stampaLista(top);


    break;





    case 2: /* Se l'utente preme il tasto 2 si cerca se c'e il libro e richiedere un libro tramite il codice*/


      fp = fopen("Libri.txt","r");


      if (fp == NULL) gestioneErrore();


     printf("\nInserisci il titolo del libro:");


     scanf("%s", titoloricerca);


     fscanf(fp, "%s", titolofile);


     while (!feof(fp))


     {


      if (strcmp(titolofile,titoloricerca)==0){


        printf("\n Il libro cercato e' presente nell'archivio ed il libro e' disponibile %s!\n", titoloricerca);


               


          cont++;


          


          printf("Inserisci il nome: ");


          scanf("%s", &nome);


          printf("Inserisci il cognome: ");


          scanf("%s", &cognome);


          printf("Inserisci il matricola: ");


          scanf("%s", &matricola);


          printf("\noperazione effettuata con successo\n");


         


          break


      }


         else


      fscanf(fp, "%s", titoloricerca);


          printf("Il libro cercato non e' presente nell'archivio ed il libro non e' disponibile\n");


     }


    // printf("Il libro cercato non e' presente nell'archivio ed il libro non e' disponibile\n");


   


        fclose(fp);


   


        break;





case 3: /* Case costruito per restituire un libro tramite codice*/


        fp = fopen("Libri.txt","r");


        if (fp == NULL) gestioneErrore();


        printf("Inserisci il titolo del libro da restituire: ");


        scanf("%s", &titolo);


        printf("Inserisci autore del libro da restituire: ");


        scanf("%s", &autore);


        printf("Inserisci il codice del libro da restituire: ");


        scanf("%d", &id);


        while (!feof(fp))


            {


              for(int i=0; i<n; i++){


                 


              }


            }


        fclose(fp);


        break;





case 4: /*esegui richiesta*/








        break ;








case 5: /*Se l'utente vuole uscire dalla biblioteca*/








printf("Grazie per aver scelto il servizio di gestione della biblioteca, torna a trovarci!\n");








        break;

















default: /*Se l'utente sbaglia ad inserire il numero*/








        printf("Questo tasto non consente di effetuare scelte! Riprova!\n");








        break;

















      } /*Fine switch*/








   } /*Fine do*/








    return scelta;





} /*Fine main*/





int menu(){


int scelta; /*Questa variabile sarà utilizzata nella switch per decidere che cosa fare...*/


    printf("* * * * * * * * * * * * * * * * * * *  \nBenvenuto nel programma di gestione biblioteca\n* * * * * * * * * * * * * * * * * * *  \n");


    





    printf(" 1. Mostra archivio\n");


    printf(" 2. Richiedi libro\n");


    printf(" 3. Restituire libro\n");


    printf(" 4. Esegui richiesta\n");


    printf(" 5. Uscire\n");


    printf("Inserisci scelta:");


    scanf("%d",&scelta); /*Viene inserito nella variabile var il numero inserito dall'utente e di conseguenza inserito nel ciclo Switch*/


    while(scelta<0 || scelta>5) {     printf("Questo tasto non consente di effetuare scelte! Riprova!\n");


        printf("Scelta: ");


        scanf("%d", &scelta);


      return scelta;


 }


  return scelta;


}





struct libri *nuovoNodo(char *titolo,char *autore, int cod_id)


{


  struct libri *nodo;





  nodo = (struct libri *) malloc(sizeof(struct libri));


  if (nodo == NULL) return NULL;


  strcpy(nodo->titolo,titolo);


  strcpy(nodo->autore, autore);


  nodo->cod_id =cod_id;


  nodo->next = NULL;


    


  return nodo;


}








struct libri *inserisciLista(struct libri *nodo, struct libri *lista)


{


  if (lista==NULL) return nodo;


  lista->next = inserisciLista(nodo, lista->next);


  return lista;


}








void gestioneErrore()


{


  printf("Errore\n");





  exit(0);


}





struct libri *leggiFile(FILE *fp, struct libri *lista)


{


  char titolo[256], autore[256];


  int cod_id;


  struct libri *nodo;





  while(fscanf(fp,"%s%s%d",titolo,autore,&cod_id)==3){


    nodo = nuovoNodo(titolo,autore,cod_id);


    if (nodo == NULL)


        gestioneErrore();


    lista = inserisciLista(nodo, lista);


  }


  return lista;


}





void scriviFile(FILE *fp, struct libri *lista) {


  while (lista!=NULL) {


    fprintf(fp,"%s %s %d \n",lista->titolo,lista->autore,lista->cod_id);


    lista = lista->next;


  }


}





void stampaLista(struct libri *top)


{


    if (top == NULL) {


        printf("\n--------------\n\n");


    }else


       if (top!=NULL && top->titolo!=0) {


printf("%s %s %d", top->titolo,  top->autore, &top->cod_id);


    stampaLista(top->next);





    }





}


//struct libri *CREA_LISTA(struct libri *TOP){


//struct libri *tmp=(struct libri*)malloc(sizeof(struct libri));


//tmp->next=TOP;


//strcpy(tmp->titolo,TOP->titolo);


//strcpy(tmp->autore,TOP->autore);


//tmp->cod_id=TOP->cod_id;


//return tmp;


//}





void scriviLista(struct libri *lista) {





    while (lista!=NULL) {


    printf("%s %s %d\n",lista->titolo,lista->autore,lista->cod_id);


    lista = lista->next;


    {


    printf("\n");


      }


   }


}
so che magari chiedo troppo ma potresti effettuare tu le modifiche poi io lo continuo?
Post unito automaticamente:

Non ho esperienza con Xcode, ma mi sembra strano che ti faccia compilare del codice con errori sintattici. Da quel che ho letto Xcode utilizza Clang come compilatore per il C, e se provi a compilare il tuo codice con questo tool online, vedrai che ti dà gli stessi errori che ti ho evidenziato prima. Quest'altro invece utilizza Gcc.
Potresti provare a seguire questa guida per attivare i warning in Xcode. Per il resto mi è un po' difficile aiutarti visto che non avendo il file.

Per quanto riguarda la ricerca, non capisco perché, a differenza delle funzioni per stampare la lista, hai deciso di passare un puntatore a puntatore a struct libri. Ti basta passare un puntatore a struct libri (cioè la lista), come per le altre funzioni, e vedrai che funziona. Non ho capito nemmeno la funzione del parametro 'num_l', così come non è molto logico l'uso di un for che scandisce la lista fino a questo valore. Non è un array, ti basta fare un while usando come condizione l != NULL && trovato != 1, in modo da uscire dal ciclo non appena il flag 'trovato' assume valore 1. Altrimenti, verrà scandita comunque tutta la lista.
Detto ciò, non so esattamente come debba essere formattato il file all'interno del quale fai la ricerca, ma, dato che nella realtà di solito i titoli dei libri e i nomi delle persone hanno degli spazi al loro interno, dovresti gestire il file e l'input in modo appropriato, ad esempio usando come separatore una virgola (o meglio un altro carattere che non può comparire all'interno dei nomi) e non lo spazio, e usando fgets invece di scanf, ad esempio.
Poi non funziona l'uscita dal programma, nel senso che quando digiti '5' il ciclo ricomincia, perché non hai posto come condizione che quando si digita '5' si esca.
ho modificato perche non mi funzionava la ricerca
Post unito automaticamente:

siccome non riesco a mandarlo senza linea bianche lo allego
Codice:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXLEN 100
struct libri{
  char titolo[100];
char autore[100];
int cod_id;
struct libri *next;
};
typedef struct libri* List;
typedef struct {
    struct libri elementi[100];
  int num_libri;
}Libro;


int Cerca_Titolo(Libro list ,char titolo);
List initList(char titolo,char autore,int cod_id);
List insertTail(List L, char name[100], int age);
//struct libri *CREA_LISTA(struct libri *TOP);
int menu(void);
struct libri *leggiFile(FILE *fp, struct libri *lista);
void scriviLista(struct libri *lista);
void scriviFile(FILE *fp, struct libri *lista);
struct libri *nuovoNodo(char *titolo,char *autore, int cod_id);
void gestioneErrore(void);
void freeLista(struct libri *lista);
void stampaLista(struct libri *top);
int main() {
  int scelta;
FILE *fp;
struct libri *lista=NULL;


    struct lista *top = NULL;


    int cod_id;


    char titolo;


    char autore;


    struct libri L;


    int presenza;


    Libro l;


    char titoloricerca[MAXLEN], titolofile[MAXLEN];


    int cont=0;


    char nome;


    char cognome;


    char matricola;


    int id;


    int n ;


  





//lista = nuovoNodo(titolo,autore,cod_id);


//CREA_LISTA(lista);


//lista = inserisciLista(L,autore);





while((scelta = menu())){


switch (scelta) /* Creo uno switch con 5 case, uno per ogni possibile scelta */





{


case 1: /*stampa lista*/





       fp = fopen("Libri.txt","r");


        if (fp == NULL) gestioneErrore();


        lista = leggiFile(fp, lista);


        fclose(fp);


        scriviLista(lista);


        //stampaLista(top);


    break;





    case 2: /* Se l'utente preme il tasto 2 si cerca se c'e il libro e richiedere un libro tramite il codice*/


      fp = fopen("Libri.txt","r");


      if (fp == NULL) gestioneErrore();


     printf("\nInserisci il titolo del libro:");


     scanf("%s", titoloricerca);


     fscanf(fp, "%s", titolofile);


     while (!feof(fp))


     {


      if (strcmp(titolofile,titoloricerca)==0){


        printf("\n Il libro cercato e' presente nell'archivio ed il libro e' disponibile %s!\n", titoloricerca);


              


          cont++;


         


          printf("Inserisci il nome: ");


          scanf("%s", &nome);


          printf("Inserisci il cognome: ");


          scanf("%s", &cognome);


          printf("Inserisci il matricola: ");


          scanf("%s", &matricola);


          printf("\noperazione effettuata con successo\n");


        


          break


      }


         else


      fscanf(fp, "%s", titoloricerca);


          printf("Il libro cercato non e' presente nell'archivio ed il libro non e' disponibile\n");


     }


    // printf("Il libro cercato non e' presente nell'archivio ed il libro non e' disponibile\n");


  


        fclose(fp);


  


        break;





case 3: /* Case costruito per restituire un libro tramite codice*/


        fp = fopen("Libri.txt","r");


        if (fp == NULL) gestioneErrore();


        printf("Inserisci il titolo del libro da restituire: ");


        scanf("%s", &titolo);


        printf("Inserisci autore del libro da restituire: ");


        scanf("%s", &autore);


        printf("Inserisci il codice del libro da restituire: ");


        scanf("%d", &id);


        while (!feof(fp))


            {


              for(int i=0; i<n; i++){


                


              }


            }


        fclose(fp);


        break;





case 4: /*esegui richiesta*/








        break ;








case 5: /*Se l'utente vuole uscire dalla biblioteca*/








printf("Grazie per aver scelto il servizio di gestione della biblioteca, torna a trovarci!\n");








        break;

















default: /*Se l'utente sbaglia ad inserire il numero*/








        printf("Questo tasto non consente di effetuare scelte! Riprova!\n");








        break;

















      } /*Fine switch*/








   } /*Fine do*/








    return scelta;





} /*Fine main*/





int menu(){


int scelta; /*Questa variabile sarà utilizzata nella switch per decidere che cosa fare...*/


    printf("* * * * * * * * * * * * * * * * * * *  \nBenvenuto nel programma di gestione biblioteca\n* * * * * * * * * * * * * * * * * * *  \n");


   





    printf(" 1. Mostra archivio\n");


    printf(" 2. Richiedi libro\n");


    printf(" 3. Restituire libro\n");


    printf(" 4. Esegui richiesta\n");


    printf(" 5. Uscire\n");


    printf("Inserisci scelta:");


    scanf("%d",&scelta); /*Viene inserito nella variabile var il numero inserito dall'utente e di conseguenza inserito nel ciclo Switch*/


    while(scelta<0 || scelta>5) {     printf("Questo tasto non consente di effetuare scelte! Riprova!\n");


        printf("Scelta: ");


        scanf("%d", &scelta);


      return scelta;


}


  return scelta;


}





struct libri *nuovoNodo(char *titolo,char *autore, int cod_id)


{


  struct libri *nodo;





  nodo = (struct libri *) malloc(sizeof(struct libri));


  if (nodo == NULL) return NULL;


  strcpy(nodo->titolo,titolo);


  strcpy(nodo->autore, autore);


  nodo->cod_id =cod_id;


  nodo->next = NULL;


   


  return nodo;


}








struct libri *inserisciLista(struct libri *nodo, struct libri *lista)


{


  if (lista==NULL) return nodo;


  lista->next = inserisciLista(nodo, lista->next);


  return lista;


}








void gestioneErrore()


{


  printf("Errore\n");





  exit(0);


}





struct libri *leggiFile(FILE *fp, struct libri *lista)


{


  char titolo[256], autore[256];


  int cod_id;


  struct libri *nodo;





  while(fscanf(fp,"%s%s%d",titolo,autore,&cod_id)==3){


    nodo = nuovoNodo(titolo,autore,cod_id);


    if (nodo == NULL)


        gestioneErrore();


    lista = inserisciLista(nodo, lista);


  }


  return lista;


}





void scriviFile(FILE *fp, struct libri *lista) {


  while (lista!=NULL) {


    fprintf(fp,"%s %s %d \n",lista->titolo,lista->autore,lista->cod_id);


    lista = lista->next;


  }


}





void stampaLista(struct libri *top)


{


    if (top == NULL) {


        printf("\n--------------\n\n");


    }else


       if (top!=NULL && top->titolo!=0) {


printf("%s %s %d", top->titolo,  top->autore, &top->cod_id);


    stampaLista(top->next);





    }





}


//struct libri *CREA_LISTA(struct libri *TOP){


//struct libri *tmp=(struct libri*)malloc(sizeof(struct libri));


//tmp->next=TOP;


//strcpy(tmp->titolo,TOP->titolo);


//strcpy(tmp->autore,TOP->autore);


//tmp->cod_id=TOP->cod_id;


//return tmp;


//}





void scriviLista(struct libri *lista) {





    while (lista!=NULL) {


    printf("%s %s %d\n",lista->titolo,lista->autore,lista->cod_id);


    lista = lista->next;


    {


    printf("\n");


      }


   }


}
so che magari chiedo troppo ma potresti effettuare tu le modifiche poi io lo continuo?
Post unito automaticamente:


ho modificato perche non mi funzionava la ricerca
no e matricola e per lo studente..perche richiedere un libro l'ho pensato come ricercare nell'archivio e se disponibile lo studente da il nome e la matricola
 

fabio93

Utente Attivo
609
173
CPU
AMD Ryzen 5 2400G
Dissipatore
Arctic Alpine64 Plus
Scheda Madre
Gigabyte GA-AX370-Gaming 3
HDD
Crucial MX500 250 GB, Crucial BX500 240 GB
RAM
G.Skill F4-3200C14D-16GFX FlareX 16 GB
Monitor
HP 2010i
PSU
Corsair TX550M
Case
Sharkoon M25-W
Periferiche
Magicforce 68, Logitech G203
OS
Windows 10 Pro, Fedora 31
Ti ho già detto tutto quello che c'è da fare. E comunque, senza offesa, così com'è formattato il codice non si capisce niente.
Per quanto riguarda la ricerca tramite lettura da file, potresti leggere una riga alla volta con fgets, memorizzando il risultato in un array temporaneo, e poi, da questo, ricavare la sottostringa fino al primo spazio, che rappresenta il titolo del libro, con sscanf, così:
Codice:
char buf[100];
// il valore di ritorno della fgets andrebbe controllato
fgets(buf, 100, fp); // legge un'intera riga dal file e la memorizza in buf
sscanf(buf, "%s", titolofile); // estrae da buf la prima sottostringa fino a uno spazio
Ma ti ripeto che andava molto meglio l'approccio iniziale di cercare nella lista, dato che comunque devi caricare tutto il file nella lista. Non è diverso dalla funzione che hai già scritto per stampare la lista, solo che anziché stampare, devi confrontare il titolo con quello da cercare. Ti faccio un esempio:
Codice:
while (l != NULL && trovato != 1) {
    if(strcmp(l->titolo, titolo)==0) {
        printf("\n Libro trovato");
        trovato=1;
    }
    l = l->next;
}

if(trovato != 1)
    printf("\n Libro non trovato");
Più di così non so come aiutarti, anche perché il regolamento di sezione vieta la risoluzione di compiti scolastici, quindi non posso riscriverti tutto il programma.
 

sare1234

Utente Attivo
262
3
Ti ho già detto tutto quello che c'è da fare. E comunque, senza offesa, così com'è formattato il codice non si capisce niente.
Per quanto riguarda la ricerca tramite lettura da file, potresti leggere una riga alla volta con fgets, memorizzando il risultato in un array temporaneo, e poi, da questo, ricavare la sottostringa fino al primo spazio, che rappresenta il titolo del libro, con sscanf, così:
Codice:
char buf[100];
// il valore di ritorno della fgets andrebbe controllato
fgets(buf, 100, fp); // legge un'intera riga dal file e la memorizza in buf
sscanf(buf, "%s", titolofile); // estrae da buf la prima sottostringa fino a uno spazio
Ma ti ripeto che andava molto meglio l'approccio iniziale di cercare nella lista, dato che comunque devi caricare tutto il file nella lista. Non è diverso dalla funzione che hai già scritto per stampare la lista, solo che anziché stampare, devi confrontare il titolo con quello da cercare. Ti faccio un esempio:
Codice:
while (l != NULL && trovato != 1) {
    if(strcmp(l->titolo, titolo)==0) {
        printf("\n Libro trovato");
        trovato=1;
    }
    l = l->next;
}

if(trovato != 1)
    printf("\n Libro non trovato");
Più di così non so come aiutarti, anche perché il regolamento di sezione vieta la risoluzione di compiti scolastici, quindi non posso riscriverti tutto il programma.
sisi tranquillo ma se uso il secondo metodo poi nella scelta basta che scrivo ricerca(titolo) giusto?
 
Stato
Discussione chiusa ad ulteriori risposte.

Ci sono discussioni simili a riguardo, dai un'occhiata!

Entra

oppure Accedi utilizzando
Discord Ufficiale Entra ora!

Discussioni Simili