Esercizio C sui file

di il
13 risposte

Esercizio C sui file

Salve ragazzi, vorrei una mano in quanto il mese prossimo ho l'esame di programmazione e, non avendo seguito il corso, in prima istanza è forse meglio chiedere consiglio a qualcuno più esperto =)
Il testo da analizzare è il seguente:
Si supponga che in un file di testo siano presenti i guadagni di alcuni alberghi organizzati nel
seguente modo: sul ciascun rigo è presente il nome di un albergo seguito dal carattere ';', poi il numero
di clienti ospitati ed infine i pagamenti di ciascun cliente separati da uno o più spazi. Un possibile
esempio è il seguente:
Hotel Belvedere; 3 60 70 60
Hotel Vesuvio; 2 120 130
Hotel Miramare; 4 120 130 60 150
Scrivere una procedura che legga da tale file e stampi a video il nome dell'albergo che ha guadagnato di
più.
Il mio svolgimento è il seguente:
#include<stdio.h>
#include<stdlib.h>

typedef struct dati{
char n_a[20];
int n_c;
float acq[7];
} hotel;

void leggi_hotel(hotel *p,int n_l);
void max_prx(hotel *p, float *tot,int n_l);

int main(){
hotel *p;
int n_l;
float tot[n_l];


leggi_hotel(p,n_l);
max_prx(p,tot,n_l);

system("PAUSE");
}

void leggi_hotel(hotel *p, int n_l){
char nomefile[20],c;
int i,j;
FILE *f;

n_l=0;

printf("Inserisci il nome del file");
scanf("s",nomefile);

f=fopen(nomefile,"r");
if(f==NULL)
printf("Impossibile aprire il file");
else{
while(c=getchar()!=EOF)
if (c=='\n')
n_l++;
}

p=(hotel*)malloc(n_l*sizeof(hotel));

for(i=0;i<n_l;i++){
   while(c=getchar()!=';')
    fscanf(f,"%s",&p[i].n_a);
        for(c=getchar()==';';c=getchar()=='/n';)
        fscanf(f,"%d",&p[i].n_c);
            for(j=0;j<p[i].n_c;j++)
            fscanf(f,"f",&p[i].acq[j]);
}
}

void max_prx(hotel *p, float *tot,int n_l){
int i,j, indice;
float maxi=0;

for (i=0;i<n_l;i++){
for(j=0;j<p[i].n_c;j++){
tot[i]+=p[i].acq[j];
}
}

maxi=tot[0];
for(i=0;i<n_l;i++)
if(maxi<tot[i]){
maxi=tot[i];
i=indice;
}

printf("L'hotel dei nababbi è il %s con %f",p[indice].n_a,maxi);
}
Alcuni vettori hanno dimensione fissa in quanto, esplicando una variabile come dimensione, non so perché il compilatore mi dava errore!
Il problema che sorge non è in fase di compilazione, ma in esecuzione mi da Core Dump.
Ringrazio anticipatamente per un eventuale aiuto =) =)

13 Risposte

  • Re: Esercizio C sui file

    Queste linee

    int n_l;
    float tot[n_l];

    non hanno senso in quando il valore di n_l non è conosciuto e il vettore ha dimensioni non certe.
    Fra l'altro funziona solo su compilatore standard C99 che supportano i VLA. Sugli altri devi usare delle dimensioni costanti oppure lavorare con l'allocazione dinamica della memoria.


    P.S. Sarebbe meglio seguirlo il corso prima di affrontare la materia ...
  • Re: Esercizio C sui file

    Grazie della dritta, hai sicuramente ragione =) Comunque ho seguito programmazione uno, le altre cose non mi sono state difficili =) Solo che ovviamente è sempre meglio avere una "guida"
  • Re: Esercizio C sui file

    Tra l'altro usi getchar() in un modo sbagliato secondo me:
    
    #include <stdio.h>
    
    int main()
    {
    int c;
    while ( (c = getchar() ) != EOF)
    putchar(c);
    return 0;
    }
    
    Le parentesi sono necessarie perché l'operatore != ha precedenza maggiore rispetto a = quindi l'istruzione:

    c = getchar() != EOF

    è equivalente a:

    c = (getchar() != EOF)

    Questo ha l'indesiderato effetto di cambiare in valore di c a 0 o 1, in base a cosa restituisce la getchar, se EOF o meno.
  • Re: Esercizio C sui file

    Ps: per il resto va bene? =)
  • Re: Esercizio C sui file

    Vero... devo mettere la parentesi, hai ragione!
  • Re: Esercizio C sui file

    Ad esempio adesso il terminale si freeza dopo aver preso il nome del file...
    f=fopen(nomefile,"r");
    if(f==NULL)
    printf("\nImpossibile aprire il file");
    else{
    while((c=getchar())!=EOF)
    if (c=='\n')
    n_l++;
    }
    il problema sembra essere qui
  • Re: Esercizio C sui file

    Beh è ovvio...
    Non è che si freeza, è che si aspetta da tastiera l'EOF...
    Per leggere carattere per carattere da file devi fare qualcosa di simile con la fgetc:
    f=fopen(nomefile,"r");
    if(f==NULL)
         {
         printf("\nImpossibile aprire il file");
         exit(1);
         }
    n_l=0;
    while((c=fgetc(f))!=EOF)
         if (c=='\n')
             n_l++;
  • Re: Esercizio C sui file

    #include<stdio.h>
    #include<stdlib.h>
    
    typedef struct h{
    char nome_hotel;
    int numero_clienti;
    float *totale;
    } hotel;
    
    void leggi_dati(hotel *p,int n_l);
    void max_guadagno(hotel *p, int n_l);
    
    int main(){
    hotel *p;
    int n_l;
    
    leggi_dati(p,n_l);
    max_guadagno(p,n_l);
    
    free(p);
    
    
    system("PAUSE");
    }
    
    void leggi_dati(hotel *p,int n_l){
    int i,j;
    FILE *f;
    char nome_file[20], c;
    
    n_l=0;
    
    printf("Inserisci il nome del file: ");
    scanf("%s",&nome_file);
    
    f=fopen(nome_file,"r");
    if(f==NULL){
        printf("Impossibile aprire il file, Jhonny");
        exit(1);
    }
    else{
        while((c=fgetc(f))!=EOF)
            if((c=fgetc(f))=='\n')
                n_l++;
    
    p=(hotel*)malloc(n_l*sizeof(hotel));
    
    while((c=fgetc(f))!=';')
        fscanf(f, "%s",&p[i].nome_hotel);
            for((c=fgetc(f))==';';(c=fgetc(f))=='\n';){
                fscanf(f,"&d",&p[i].numero_clienti);
                p[i].totale=(float*)malloc((p[i].numero_clienti)*sizeof(float));
                for(j=0;j<p[i].numero_clienti;j++){
                fscanf(f,"%f",&p[i].totale[j]);
            }
            }
    
    }
    
    
    fclose(f);
    }
    
    void max_guadagno(hotel *p, int n_l){
    int i,j, indice;
    float tot[n_l];
    float Max;
    
    for(i=0;i<n_l;i++){
        for(j=0;j<p[i].numero_clienti;j++)
            tot[i]+=p[i].totale[j];
    }
    
    Max=tot[0];
    
    for(i=0;i<n_l;i++){
       if(Max<tot[i]){
        Max=tot[i];
        indice=i;
       }
    }
    
    printf("L'hotel dei nababbi è %s con un guadagno di %f",p[indice].nome_hotel,tot[i]);
    }
    
    
    Nessun errore sintattico, ma comunque si blocca
  • Re: Esercizio C sui file

    scanf("%s",&nome_file);
    questo è un errore!
    for( (c=fgetc(f)) ==';' ;(c=fgetc(f))=='\n';)
    questo è un'altro errore.
    fscanf(f,"&d",&p[i].numero_clienti);
    qui ne abbiamo un'altro.
    printf("L'hotel dei nababbi è %s con un guadagno di %f",p[indice].nome_hotel,tot[i]);
    fscanf(f, "%s",&p[i].nome_hotel);
    leggi_dati(p,n_l);
    Ecco ora scaricati CODE::BLOCKS e butta nel cesso dev-c++,vedrai che mi ringrazierai.
  • Re: Esercizio C sui file

    Utilizzo quello :S
  • Re: Esercizio C sui file

    Nessun errore sintattico, ma comunque si blocca
    Code::Blocks ne segnala 8.
    system("PAUSE");
    questo sgorbio lo usa solo ed esclusivamente dev-c++
    L'indentazione orribile è causata da quella ciofeca del ces-c++


    Dimenticavo la cosa piu fondamentale,sei tu che devi imparare,e con quel coso non ce la farai mai!Meglio il notepad di windows almeno li non ti da errori inesistenti ma quelli reali!
  • Re: Esercizio C sui file

    Ma come io uso codeblocks :S com'è possibile che a me non li vede? Mai usato il dev, m'ha fatto sempre schifo
  • Re: Esercizio C sui file

    Perchè usi quell'orrendo system pause allora?
    come mai usi quell'orrenda indentazione? riesci a leggere il codice che hai postato?

    Hai reso il codice troppo complesso in base alle tue conoscenze.
    Ti posto un esempio di codice che utilizza le liste,anche se non so se le conosci.
    Guarda come è strutturato e indentato il codice.
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    #define HOTEL_NAME_MAX 100
    #define BUFFER_FILE 1000
    
    typedef struct _HOTEL
    {
        char name[HOTEL_NAME_MAX];
        int nclient;
        int *guadagni;
        struct _HOTEL* next;
    }HOTEL;
    
    typedef struct _GESTIONEHOTEL
    {
        HOTEL* first;
        int nhotel;
    }GESTIONEHOTEL;
    
    /// ///////////////// ///
    /// SUPPORT STRUCTURE ///
    /// ///////////////// ///
    
    HOTEL* hotel_new(const char* name,int nclient)
    {
        HOTEL* h = malloc(sizeof(HOTEL));
    
        h->next = NULL;
    
        strcpy(h->name,name);
    
        h->nclient = nclient;
        if (nclient == 0)
        {
            h->guadagni = 0;
        }
        else
        {
            h->guadagni = malloc(sizeof(int*) * nclient);
        }
    
        return h;
    }
    
    void gestionehotel_add(GESTIONEHOTEL* gh,HOTEL* h)
    {
        if (gh->first == NULL)
        {
            gh->first = h;
            gh->nhotel = 1;
            return;
        }
    
        HOTEL* last = gh->first;
        for ( ; last->next != NULL ; last = last->next);
    
        last->next = h;
        ++gh->nhotel;
    }
    
    /// ///////////// ///
    /// SUPPORT FILE ///
    /// //////////// ///
    
    HOTEL* hotel_read(FILE* f)
    {
        char buffer[BUFFER_FILE];
    
        if ( fgets(buffer,BUFFER_FILE,f) == NULL ) return NULL;
    
        if (buffer[strlen(buffer)-1] == '\n')
            buffer[strlen(buffer)-1] = '\0';
    
        char tokenh[HOTEL_NAME_MAX];
        char* tptr;
    
        tptr = strchr(buffer,';');
        strncpy(tokenh,buffer,tptr - buffer);
        tokenh[tptr - buffer] = '\0';
    
        char* iptr;
        int nc;
        char token[HOTEL_NAME_MAX];
    
        ++tptr;
        if (*tptr == ' ') ++tptr;
    
        iptr = strchr(tptr,' ');
        strncpy(token,tptr,iptr - tptr);
        token[iptr-tptr] = '\0';
    
        nc = atoi(token);
        tptr = iptr + 1;
    
        HOTEL* h = hotel_new(tokenh,nc);
    
        int i;
        for ( i = 0 ; i < h->nclient ; i++)
        {
            iptr = strchr(tptr,' ');
            if (iptr == NULL)
                strcpy(token,tptr);
            else
            {
                strncpy(token,tptr,iptr - tptr);
                token[iptr-tptr] = '\0';
            }
    
            nc = atoi(token);
            h->guadagni[i] = nc;
            tptr = iptr + 1;
        }
    
        return h;
    }
    
    /// ///////////// ///
    /// START PROGRAM ///
    /// ///////////// ///
    
    
    int main()
    {
        GESTIONEHOTEL gh;
                      gh.first = NULL;
    
        char input[BUFFER_FILE];
    
        printf("Gestione Hotel\n");
    
        printf("Insert path file:");
            gets(input);
    
        FILE* f;
        if ( (f = fopen(input,"r")) == NULL)
        {
            printf("Error to open file\n");
            return -1;
        }
    
        printf("Loading...");
    
        HOTEL* h;
        while ( (h = hotel_read(f)) )
            gestionehotel_add(&gh,h);
    
        fclose(f);
    
        printf("readed %d hotel.ok\n",gh.nhotel);
    
        printf("Nome Hotel,Media guadagno:\n");
    
        for ( h = gh.first ; h != NULL ; h = h->next)
        {
            int i;
            float media;
            for ( i = 0,media = 0.0 ; i < h->nclient ; i++)
                media += h->guadagni[i];
            media /= h->nclient;
    
            printf("\t%s %f\n",h->name,media);
        }
    
        return 0;
    }
    
Devi accedere o registrarti per scrivere nel forum
13 risposte