RISOLTO [C] Esercizio gestione biblioteca

Stato
Discussione chiusa ad ulteriori risposte.

sare1234

Utente Attivo
262
3
Mi intrometto solo per farti notare una cosa, mi è caduto subito l'occhio lì...

C:
    char nome;
    char matricola;
    char cognome;
    printf("\nInsersici il titolo del codice da cercare:");
    scanf("%s", &titolo);

while (l != NULL && trovato != 1) {
    if(strcmp(l->titolo, &titolo)==0) {
printf("\nIl libro cercato e' presente nell'archivio ed il libro e' disponibile");
        printf("\nInserisci nome: ");
        scanf("%s", &nome);
        printf("\nInserisci cognome: ");
        scanf("%s", &cognome);
        printf("\nInserisci matricola: ");
        scanf("%s", &matricola);
        printf("\nOperazione effettuata con successo\n");
        trovato=1;
   }
    l = l->next;
  }

Se stai usando un char per un cognome ed un nome, come puoi leggere una stringa? :)
Stesso discorso per la matricola, che non sarà solo 1 carattere.
si lo so devo scrivere:
Codice:
char nome[10]
dopo aggiusto tutto..però volevo risolvere il problema della stampa
 

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 programma non funziona proprio perché non hai ancora corretto gli errori che sia io che @DispatchCode ti abbiamo indicato.
Dovresti anche porre la condizione di uscita dal while, ad esempio come while((scelta = menu()) != 5), altrimenti il programma non termina mai. Inoltre ti suggerisco di attivare la compilazione con tutti i warning (ad esempio in gcc si fa con l'opzione -Wall) che ti avvisa anche di eventuali variabili inutilizzate (e quindi eliminabili, a meno che tu non voglia usarle dopo).
 

sare1234

Utente Attivo
262
3
Il programma non funziona proprio perché non hai ancora corretto gli errori che sia io che @DispatchCode ti abbiamo indicato.
Dovresti anche porre la condizione di uscita dal while, ad esempio come while((scelta = menu()) != 5), altrimenti il programma non termina mai. Inoltre ti suggerisco di attivare la compilazione con tutti i warning (ad esempio in gcc si fa con l'opzione -Wall) che ti avvisa anche di eventuali variabili inutilizzate (e quindi eliminabili, a meno che tu non voglia usarle dopo).
ok ma questo while dove va inserito?
 

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
Devi semplicemente cambiare la condizione del while esistente che hai messo nel main, per intenderci quello che contiene lo switch.
 

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
Sì. A parte questo, ogniqualvolta chiedi l'input all'utente, dovresti validarlo, cioè controllare che sia del formato atteso.
Ad esempio, se hai un array di char (stringa) di 30 elementi, essendo l'ultimo dedicato al carattere di terminazione '\0', dovresti impedire che l'utente possa inserire una stringa più lunga, altrimenti hai buffer overflow, cioè scavalchi i confini dell'array. Se usi scanf, puoi inserire il numero max di caratteri tra '%' e 's', ad es. per leggere fino a 29 caratteri, '%29s'. Meglio però usare fgets, come ti ho detto all'inizio di questo thread, in modo da gestire più facilmente anche la presenza degli spazi. E, lo ripeto ancora, sfrutta l'aiuto del compilatore, leggi i warning che ti dà e cerca di interpretarli.
 
  • Mi piace
Reazioni: Mursey

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 devi includere gli apici (' '), gli ho messi per distinguere il codice dal resto del testo, forse hai equivocato. Devi semplicemente inserire il numero max di caratteri da leggere tra % e s.
 

sare1234

Utente Attivo
262
3
Sì. A parte questo, ogniqualvolta chiedi l'input all'utente, dovresti validarlo, cioè controllare che sia del formato atteso.
Ad esempio, se hai un array di char (stringa) di 30 elementi, essendo l'ultimo dedicato al carattere di terminazione '\0', dovresti impedire che l'utente possa inserire una stringa più lunga, altrimenti hai buffer overflow, cioè scavalchi i confini dell'array. Se usi scanf, puoi inserire il numero max di caratteri tra '%' e 's', ad es. per leggere fino a 29 caratteri, '%29s'. Meglio però usare fgets, come ti ho detto all'inizio di questo thread, in modo da gestire più facilmente anche la presenza degli spazi. E, lo ripeto ancora, sfrutta l'aiuto del compilatore, leggi i warning che ti dà e cerca di interpretarli.
ho corretto tutto
Codice:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "funzioni.h"
int main() {
int scelta;
FILE *fp;
struct libri *lista=NULL;
char titolo[50];
char autore[20];
int id = 0;
int n ;

fp = fopen("Libri.txt","r");
if (fp == NULL) gestioneErrore();
lista = leggiFile(fp, lista);
fclose(fp);


while((scelta = menu())){
switch (scelta) /* Creo uno switch con 5 case, uno per ogni possibile scelta */
{


   case 1: /*stampa lista*/
        scriviLista(lista);
     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(lista);

    break;

    case 3: /* Case costruito per restituire un libro tramite codice*/
       printf("Quanti libri vuoi restituire?: ");
       scanf("%d", &n);
       for (int i=0; i<n; i++) {
         printf("Inserire titolo \n");
             scanf("%49s", titolo);
        printf("Inserire autore' \n");
       scanf("%19s", autore);
        printf("Inserire codice' \n");
       scanf("%d", &id);
       printf("\nLibro restituito con successo\n");
    lista = insertTail(lista, titolo, autore, id);
        }
        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");

  return 0;

   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 0;


} /*Fine main*/

Codice:
#include "funzioni.h"
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, [B]struct[/B] libri *lista)
{
    [B]char[/B] titolo[50];
    [B]char[/B] autore[20];
  [B]int[/B] cod_id;
  [B]struct[/B] libri *nodo;
  [B]while[/B](fscanf(fp,"%s%s%d",titolo,autore,&cod_id)==3){
    nodo = nuovoNodo(titolo, autore, cod_id);
    [B]if[/B] (nodo == [B]NULL[/B])
        gestioneErrore();
    lista = inserisciLista(nodo, lista);
  }
  [B]return[/B] lista;
}

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

}
[B]void[/B] scriviLista([B]struct[/B] libri *lista) {
    [B]while[/B] (lista!=[B]NULL[/B]) {
    printf("%s %s %d\n",lista->titolo,lista->autore,lista->cod_id);
    lista = lista->next;
    {
    printf("\n");

      }
   }
}

[B]void[/B] ricerca ([B]struct[/B] libri *l){
  [B]int[/B] trovato = 0 ;
    [B]char[/B] titolo[50];
    [B]char[/B] nome[256];
    [B]char[/B] matricola;
    [B]char[/B] cognome[256];
    printf("\nInsersici il titolo del codice da cercare:");
    scanf("%49s", &titolo[50]);
[B]while[/B] (l != [B]NULL[/B] && trovato != 1) {
    [B]if[/B](strcmp(l->titolo, &titolo[50])==0) {
printf("\nIl libro cercato e' presente nell'archivio ed il libro e' disponibile");
        printf("\nInserisci nome: ");
        scanf("%255s", &nome[256]);
        printf("\nInserisci cognome: ");
       scanf("%255s", &cognome[256]);
       printf("\nInserisci matricola: ");
       scanf("%s", &matricola);
      printf("\nOperazione effettuata con successo\n");
      trovato=1;

   }
    l = l->next;
  }

    [B]if[/B](trovato != 1)
        printf("\nIl libro cercato non e' presente nell'archivio ed il libro non e' disponibile\n");


}
List insertTail(List L, [B]char[/B] titolo[50], [B]char[/B] autore[20] ,[B]int[/B] cod_id) {
    [B]if[/B] (L != [B]NULL[/B]) {
  L->next = insertTail(L->next, titolo, autore, cod_id);
  }

    [B]else[/B]{
     L = initList(titolo,autore,cod_id);

    }
  [B]return[/B] L;

}

List initList([B]char[/B] titolo[50] ,[B]char[/B] autore[20] ,[B]int[/B] cod_id) {
  List L = (List)malloc([B]sizeof[/B]([B]struct[/B] libri));

    strcpy(L->titolo,&titolo[50]);
   strcpy(L->autore,&autore[20]);
   L->cod_id= cod_id;
L->next = [B]NULL[/B];
  [B]return[/B] L;
}
[code]
ho fatto cosi'..ma se non metto gli apici mi da errore ed ho ancora il problema che il titolo e autore che li inserisce sotto forma di codici
Post unito automaticamente:

image1.jpeg image0.jpeg
risoltooooo....
 
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
Scusami ma non hai corretto affatto tutti gli errori, tant'è che il codice che hai appena postato, oltre ad avere come al solito una formattazione disordinata, non compila (anche perché ti sei dimenticato la definizione della struct libri)!
Ci sono ancora tutti gli errori tipo scanf("%s", &matricola);, quando ti ho detto più e più volte che la & non si mette con le stringhe (e vabbè, alcuni compilatori lo accettano, ma è comunque sbagliato, se non altro concettualmente). Oppure, un altro errore è scanf("%255s", &cognome[256]);: non devi inserire la dimensione dell'array, non è mica la dichiarazione questa. Così vuol dire che tenti di memorizzare una stringa nell'elemento di indice 256 dell'array! E te l'ho spiegato già ieri...
Alla fine i tuoi errori sono sempre gli stessi, se non li correggi è ovvio che non risolvi.
 

sare1234

Utente Attivo
262
3
Scusami ma non hai corretto affatto tutti gli errori, tant'è che il codice che hai appena postato, oltre ad avere come al solito una formattazione disordinata, non compila (anche perché ti sei dimenticato la definizione della struct libri)!
Ci sono ancora tutti gli errori tipo scanf("%s", &matricola);, quando ti ho detto più e più volte che la & non si mette con le stringhe (e vabbè, alcuni compilatori lo accettano, ma è comunque sbagliato, se non altro concettualmente). Oppure, un altro errore è scanf("%255s", &cognome[256]);: non devi inserire la dimensione dell'array, non è mica la dichiarazione questa. Così vuol dire che tenti di memorizzare una stringa nell'elemento di indice 256 dell'array! E te l'ho spiegato già ieri...
Alla fine i tuoi errori sono sempre gli stessi, se non li correggi è ovvio che non risolvi.
sii ho risolto....solo ora devo gestire un'insieme di richieste ed accettarle o rifiutare avevo pensato di utilizzare una coda...oppure mi puoi suggerire qualcos'altro?
 

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
Se il codice con cui hai risolto è quello che hai postato per ultimo ci sono ancora molti errori, quindi è sbagliato. Non so come faccia Xcode a compilartelo. Molto probabilmente l'errore degli screenshot è dovuto al fatto che qui c'è un errore di cui ti ho parlato prima, dovresti riconoscerlo
List initList(char titolo[50] ,char autore[20] ,int cod_id) { List L = (List)malloc(sizeof(struct libri)); strcpy(L->titolo,&titolo[50]); strcpy(L->autore,&autore[20]); L->cod_id= cod_id; L->next = NULL; return L;
 

sare1234

Utente Attivo
262
3
per rimuovere il libro ho fatto cosi:
Codice:
struct libri *rimuoviLibro(struct libri *lista)


{


  if (lista==NULL) return lista;


 if (ricerca == 1) {


  lista = rimuoviNodo(lista, lista);


   lista = rimuoviLibri(lista,);


  } else lista->next = rimuoviLibri(lista->next);


  


  return lista;


}
e giusto?
Post unito automaticamente:

Se il codice con cui hai risolto è quello che hai postato per ultimo ci sono ancora molti errori, quindi è sbagliato. Non so come faccia Xcode a compilartelo. Molto probabilmente l'errore degli screenshot è dovuto al fatto che qui c'è un errore di cui ti ho parlato prima, dovresti riconoscerlo
si cerano degli errori ora ho corretto ed era qui
strcpy(L->titolo,titolo); // non &titolo
Post unito automaticamente:

Scusami ma non hai corretto affatto tutti gli errori, tant'è che il codice che hai appena postato, oltre ad avere come al solito una formattazione disordinata, non compila (anche perché ti sei dimenticato la definizione della struct libri)!
Ci sono ancora tutti gli errori tipo scanf("%s", &matricola);, quando ti ho detto più e più volte che la & non si mette con le stringhe (e vabbè, alcuni compilatori lo accettano, ma è comunque sbagliato, se non altro concettualmente). Oppure, un altro errore è scanf("%255s", &cognome[256]);: non devi inserire la dimensione dell'array, non è mica la dichiarazione questa. Così vuol dire che tenti di memorizzare una stringa nell'elemento di indice 256 dell'array! E te l'ho spiegato già ieri...
Alla fine i tuoi errori sono sempre gli stessi, se non li correggi è ovvio che non risolvi.
no non l'ho dimenticata ma ho suddiviso per funzioni, metodi e main c'e pero ho postato solo l'errore che avevo
 

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

sare1234

Utente Attivo
262
3
E questo cos'è?
volevo scrivere se " il titolo è presente" allora elimina..
Post unito automaticamente:

ciao, scusa se ti disturbo di nuovo, ma non avevo capito bene la traccia per richiesta di un libro si intende che viene fatta la richiesta di avere un libro e poi nell'opzione successiva questa viene approvata....per essere approvata ho cercato se il libro e presente e poi devo eliminarlo ma come collego a questo il libro della richiesta precedente?
 
Ultima modifica:
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