Richiesta aiuto

di il
11 risposte

Richiesta aiuto

Salve a tutti, sono uno studente universitario alle prime armi nella programmazione in C. Dovendo dare la materia a giorni ho qualche dubbio che spero riusciate a risolvermi. Devo svolgere un programma che gestisca una lista dinamica che attinge dati d un file. Ho creato una funzione "creaLista" che si occupa appunto di creare la lista e inserirci dentro i dati del file. Ecco il codice:

alberghi *inizializza(char * nomefile, alberghi *p){

info elem;
alberghi *newElem;
FILE *fp;

if((fp=fopen(nomefile,"r"))!=NULL){
while(fscanf(fp,"%[^,],%s,%s,%s\n",elem.nome, &(elem.stelle), &(elem.numero), &(elem.servizio))!=EOF){
newElem = (alberghi *)malloc(sizeof(alberghi));
newElem->albergo = elem;
newElem->next = p;
p = newElem;
}
} else {
printf("Errore nell'apertura del file\n");
}

fclose(fp);

return p;
}

Quando compilo la lista non contiene tutti i dati presenti sul file, ma solo una parte, sapreste aiutrmi gentilmente?

11 Risposte

  • Re: Richiesta aiuto

    1) leggi il regolamento: DEVI usare il tag CODE
    2) manca il file di input e almeno l'ultimo elemento che è inserito correttamente
  • Re: Richiesta aiuto

    Mancano anche le strutture e il main ...
  • Re: Richiesta aiuto

    Riporto tutto il mio lavoro qui sotto, vi sarei molto grato se riusciste a risolvere il mio problema
    
    Questo è il file di header in cui ho creato la struttura e dichiarato i prototipi delle funzioni
    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    
    #define MAX 50
    
    typedef struct
    {
        char nome[MAX];
        char stelle[MAX];
        char numero[MAX];
        char servizio[MAX];
    
    }info;
    
    struct alberghi
    {
        info albergo;
        struct alberghi *next;
    };
    
    typedef struct alberghi alberghi;
    
    alberghi *inizializza(char *,alberghi *p);
    alberghi *stampa_s(alberghi *p);
    alberghi *stampa_s_s(alberghi *p);
    alberghi *inserisci(alberghi *p);
    void salva(alberghi *p);
    void printLista(alberghi *p);
    
    Questo invece è il main
    
    #include "data.h"
    
    int main()
    {
        alberghi *lista=NULL;
        int scelta;
    
        for(;;)
        {
            printf("Scegli quello che vuoi fare\n");
            printf("1)Inizializza lista\n");
            printf("2)Visualizza gli alberghi con servizio x\n");
            printf("3)Visualizza gli alberghi con stelle y e servizio x\n");
            printf("4)Inserisci albergo\n");
            printf("5)Salva\n");
            printf("6)stampa\n");
            scanf("%d",&scelta);
    
            if(scelta==1)
            {
                lista=inizializza("alberghi.txt",lista);
            }
            else if(scelta==2)
            {
                lista=stampa_s(lista);
            }
            else if(scelta==3)
            {
                lista=stampa_s_s(lista);
            }
            else if(scelta==4)
            {
                lista=inserisci(lista);
            }
            else if(scelta==5)
            {
                salva(lista);
            }
            else if (scelta==6)
            {
                printLista(lista);
            }
            else
            {
                break;
            }
        }
    }
    
    Questo è invece il file funzioni.c dove appunto implemento le funzioni
    
    #include "data.h"
    alberghi  *inizializza(char * nomefile, alberghi *p){
    
      info elem;
      alberghi *newElem;
     	FILE *fp;
    
     	if((fp=fopen(nomefile,"r"))!=NULL){
    		while(fscanf(fp,"%[^,],%s,%s,%s\n",elem.nome, &(elem.stelle), &(elem.numero), &(elem.servizio))!=EOF){
            newElem = (alberghi *)malloc(sizeof(alberghi));
            newElem->albergo = elem;
            newElem->next = p;
            p = newElem;
    		}
    	} else {
    		printf("Errore nell'apertura del file\n");
    	}
    
    	fclose(fp);
    
      return p;
    }
    
    alberghi *inserisci(alberghi *p)
    {
        char nome[MAX];
        char stelle[MAX];
        char numero[MAX];
        char servizio[MAX];
        info da_agg;
        alberghi *p2=NULL;
    
        printf("Inserisci le info dell'albergo\n");
        printf("Inserisci nome\n");
        scanf("%s",nome);
        strcpy(da_agg.nome, nome);
        printf("Inserisci stelle\n");
        scanf("%s", stelle);
        strcpy(da_agg.stelle, stelle);
        printf("Inserisci numero\n");
        scanf("%s", numero);
        strcpy(da_agg.numero, numero);
        printf("Inserisci elenco\n");
        scanf("%s",servizio);
        strcpy(da_agg.servizio, servizio);
    
        if(p!=NULL)
        {
            p2=(alberghi*)malloc(sizeof(alberghi));
            p2->albergo=da_agg;
            p2->next=p;
        }
        else
        {
            p=(alberghi*)malloc(sizeof(alberghi));
            p->next=NULL;
            p2=p;
        }
        return p2;
    }
    
    alberghi *stampa_s(alberghi *p)
    {
        char servizio[50];
        alberghi *p2;
    
        printf("Inserisci il servizio che vuoi ricercare\n");
        scanf("%s", servizio);
    
        while(p!=NULL)
        {
            if(strcmp(p2->albergo.servizio,servizio)==0)
            {
                printf("%s",p->albergo.nome);
                p=p->next;
                p2=p;
            }
            else
            {
                p=p->next;
                p2=p;
            }
        }
        return p2;
    
    }
    
    alberghi *stampa_s_s(alberghi *p)
    {
        char servizio[50];
        char stelle[10];
        alberghi *p2;
    
        printf("inserisci il servizio\n");
        scanf("%s", servizio);
        printf("inserisci il numero di stelle\n");
        scanf("%s", stelle);
    
        while(p!=NULL)
        {
            if(strcmp(p2->albergo.stelle,stelle)==0)
            {
                printf("%s",p->albergo.nome);
                p=p->next;
                p2=p;
            }
            else
            {
                p=p->next;
                p2=p;
            }
    
        }
        return p;
    }
    
    void salva(alberghi *p)
    {
        FILE *f=fopen("archivio.txt","a");
    
        while(p!=NULL)
        {
            fprintf(f,"%s/t%s\t%s\t%s\n",p->albergo.nome,p->albergo.stelle,p->albergo.numero,p->albergo.servizio);
            p=p->next;
        }
        fflush(f);
        fclose(f);
    
        return;
    }
    void printLista(alberghi *p){
      if(p==NULL){
        printf("Lista vuota.\n");
      } else {
        while(p!=NULL){
          printf("%s,%s,%s,%s\n",p->albergo, p->albergo.stelle, p->albergo.numero, p->albergo.servizio);
          p = p->next;
        }
    }
    }
    
    Qui riporto il contenuto del file alberghi.txt
    
    Miramonti, (****), 3 televisione garage aria_condizionata
    Posta, (****), 2 garage giardino
    Ambasciatori, (***), 5 televisione bagno_in_camera giardino ristorante frigo_bar
    Olimpia, (**), 0
    Vecchio_Mulino, (**), 3, ristorante garage giardino
    
  • Re: Richiesta aiuto

    Tanto per cominciare usi la variabile

    p2

    senza averla mai inizializzata

    Poi ... il testo deve essere questo

    Miramonti,(****),3,televisione garage aria_condizionata
    Posta,(****),2,garage giardino
    Ambasciatori,(***), 5,televisione bagno_in_camera giardino ristorante frigo_bar
    Olimpia,(**),0,(nessuno)
    Vecchio_Mulino,(**),3,ristorante garage giardino

    e per MAX (nel caso del campo servizio) devi prevedere 80 caratteri)

    per la fscanf così

    while (fscanf(fp, "%[^,],%[^,],%[^,],%[^\n]\n", elem.nome, &(elem.stelle), &(elem.numero), &(elem.servizio)) != EOF) {

    Inoltre nella printLista la printf deve essere

    printf("%s,%s,%s,%s\n", p->albergo.nome, p->albergo.stelle, p->albergo.numero, p->albergo.servizio);
  • Re: Richiesta aiuto

    Grazie mille sei stato davvero molto gentile e utile a spiegarmi quale fosse il problema! Adesso però dovrei chiederti un ultima cosa, come mai quando compilo ed eseguo, provando a fare la seconda o la terza scelta mi da come risultato "Segmentation fault (core drumped)" ??
  • Re: Richiesta aiuto

    Ma il codice con le correzioni lo mostri?
  • Re: Richiesta aiuto

    Ho notato che non funziona neanche la funzione inserisci funziona correttamente
    
    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    
    #define MAX 80
    
    typedef struct
    {
        char nome[MAX];
        char stelle[MAX];
        char numero[MAX];
        char servizio[MAX];
    
    }info;
    
    struct alberghi
    {
        info albergo;
        struct alberghi *next;
    };
    
    typedef struct alberghi alberghi;
    
    alberghi *inizializza(char *,alberghi *p);
    alberghi *stampa_s(alberghi *p);
    alberghi *stampa_s_s(alberghi *p);
    alberghi *inserisci(alberghi *p);
    void salva(alberghi *p);
    void printLista(alberghi *p);
    
    
    #include "data.h"
    
    int main()
    {
        alberghi *lista=NULL;
        int scelta;
    
        for(;;)
        {
            printf("Scegli quello che vuoi fare\n");
            printf("1)Inizializza lista\n");
            printf("2)Visualizza gli alberghi con servizio x\n");
            printf("3)Visualizza gli alberghi con stelle y e servizio x\n");
            printf("4)Inserisci albergo\n");
            printf("5)Salva\n");
            printf("6)stampa\n");
            scanf("%d",&scelta);
    
            if(scelta==1)
            {
                lista=inizializza("alberghi.txt",lista);
            }
            else if(scelta==2)
            {
                lista=stampa_s(lista);
            }
            else if(scelta==3)
            {
                lista=stampa_s_s(lista);
            }
            else if(scelta==4)
            {
                lista=inserisci(lista);
            }
            else if(scelta==5)
            {
                salva(lista);
            }
            else if (scelta==6)
            {
                printLista(lista);
            }
            else
            {
                break;
            }
        }
    }
    
    
    #include "data.h"
    alberghi  *inizializza(char * nomefile, alberghi *p){
    
      info elem;
      alberghi *newElem;
     	FILE *fp;
    
     	if((fp=fopen(nomefile,"r"))!=NULL){
    		while (fscanf(fp, "%[^,],%[^,],%[^,],%[^\n]\n", elem.nome, &(elem.stelle), &(elem.numero), &(elem.servizio)) != EOF) {
            newElem = (alberghi *)malloc(sizeof(alberghi));
            newElem->albergo = elem;
            newElem->next = p;
            p = newElem;
    		}
    	} else {
    		printf("Errore nell'apertura del file\n");
    	}
    
    	fclose(fp);
    
      return p;
    }
    
    alberghi *inserisci(alberghi *p)
    {
        char nome[MAX];
        char stelle[MAX];
        char numero[MAX];
        char servizio[MAX];
        info da_agg;
        alberghi *p2=NULL;
    
        printf("Inserisci le info dell'albergo\n");
        printf("Inserisci nome\n");
        scanf("%s",nome);
        strcpy(da_agg.nome, nome);
        printf("Inserisci stelle\n");
        scanf("%s", stelle);
        strcpy(da_agg.stelle, stelle);
        printf("Inserisci numero\n");
        scanf("%s", numero);
        strcpy(da_agg.numero, numero);
        printf("Inserisci elenco\n");
        scanf("%s",servizio);
        strcpy(da_agg.servizio, servizio);
    
        if(p!=NULL)
        {
            p2=(alberghi*)malloc(sizeof(alberghi));
            p2->albergo=da_agg;
            p2->next=p;
        }
        else
        {
            p=(alberghi*)malloc(sizeof(alberghi));
            p->next=NULL;
            p2=p;
        }
        return p2;
    }
    
    alberghi *stampa_s(alberghi *p)
    {
        char servizio[50];
        alberghi *p2=NULL;
    
        printf("Inserisci il servizio che vuoi ricercare\n");
        scanf("%s", servizio);
    
        while(p!=NULL)
        {
            if(strcmp(p2->albergo.servizio,servizio)==0)
            {
                printf("%s",p->albergo.nome);
                p=p->next;
                p2=p;
            }
            else
            {
                p=p->next;
                p2=p;
            }
        }
        return p2;
    
    }
    
    alberghi *stampa_s_s(alberghi *p)
    {
        char servizio[50];
        char stelle[10];
        alberghi *p2=NULL;
    
        printf("inserisci il servizio\n");
        scanf("%s", servizio);
        printf("inserisci il numero di stelle\n");
        scanf("%s", stelle);
    
        while(p!=NULL)
        {
            if(strcmp(p2->albergo.stelle,stelle)==0 && strcmp(p2->albergo.servizio,servizio)==0)
            {
                printf("%s",p->albergo.nome);
                p=p->next;
                p2=p;
            }
            else
            {
                p=p->next;
                p2=p;
            }
    
        }
        return p;
    }
    
    void salva(alberghi *p)
    {
        FILE *f=fopen("archivio.txt","a");
    
        while(p!=NULL)
        {
            fprintf(f,"%s/t%s\t%s\t%s\n",p->albergo.nome,p->albergo.stelle,p->albergo.numero,p->albergo.servizio);
            p=p->next;
        }
        fflush(f);
        fclose(f);
    
        return;
    }
    void printLista(alberghi *p){
      if(p==NULL){
        printf("Lista vuota.\n");
      } else {
        while(p!=NULL){
          printf("%s,%s,%s,%s\n", p->albergo.nome, p->albergo.stelle, p->albergo.numero, p->albergo.servizio);
          p = p->next;
        }
    }
    }
    
  • Re: Richiesta aiuto

    Perché le funzioni di ricerca non sono di tipo void dato che visualizzano i risultati?
    Le due funzioni non devono modificare lista nel main !

    E poi l'uso di p e p2 nel ciclo è sbagliato. Basta il codice come quello della printLista inserendo una opportuna if all'interno del ciclo.

    A proposito della if devi fare attenzione

    1) nella ricerca di stelle e servizi fai solo il confronto con le stelle

    2) la strcmp confronta esattamente la stringa (comprese maiuscole e minuscole) e non considera se la stringa si trova all'interno dell'altra.
    Ad esempio se cerchi "garage" e nella stringa c'è "frigo garage wifi" la strcmp non te lo dice.
  • Re: Richiesta aiuto

    Nella funzione di inserimento invece cosa c'è che non va? mi fa inserire il nome, servzio, e il numero dei servizi due volte e mi prende solo quelli del secondo inserimento
  • Re: Richiesta aiuto

    La scanf con %s non accetta frasi con parole separate da spazi. Devi usare [^\n]
  • Re: Richiesta aiuto

    Okay ho risolto il problema dell'inserimento, adesso mi resta solo qualche piccolo problema nelle due ricerche ma niente di che, ti ringrazio ancora per la disponibilità e il tempo dedicatomi!
Devi accedere o registrarti per scrivere nel forum
11 risposte