Esercizio in C:Help!!

di il
11 risposte

Esercizio in C:Help!!

Heilà!
Avrei bisogno di una mano.
Ho un esercizio che mi chiede queste cose:


1. Aprire un file
2.Leggere da file un numero naturale n che mi va a rappresentare il numero di coppie di valori. Le coppie hanno come primo valore un numero intero e come secondo uno float.
3.Devo allocare due vettori ed inserire in uno i numeri naturali e nell'altro i float
4: ritorna il numero di valori validi

Mi manca capire come inserire i valori nei due vettori.

Io lo avrei fatto in questo modo ma penso che quel pezzo sia sbagliato.
Grazie mille in anticipo!

int leggiMaree(char*nomeFile,int**mins,float**maree,int*nEl)
{
FILE*fp;
fp=fopen(nomeFile, "r");
if((fp=fopen(nomeFile, "r"))==NULL)
return 0;

int i,j, conta=0;

fscanf(fp, "%d", &*nEl);

//alloco dinamicamente i due vettori di n elementi con la funzione malloc
*mins=(int*)malloc(*nEl*sizeof(int));
*maree=(float*)malloc(*nEl*sizeof(float));

//i per le n righe e j per le 2 colonne

for(i=0;i<*nEl;i++)
{
for(j=0;j<2;j++)
{
fscanf(fp, "%d", &mins[0]);
fscanf(fp, "%f", &maree[1]);

if(*mins<0||*mins>1439)
{
printf("Valore non accettabile\n");
return 0;
}
if(*maree<-10||*maree>+10)
{
printf("Valore non accettabile\n");
return 0;
}

//verifico che i parametri siano validi ed incremento il valore da restituire

if(*mins>=0&&*mins<=1439&&*maree>0-10&&*maree<=10)
conta++;
}
}



fclose(fp);
return conta;

}

11 Risposte

  • Re: Esercizio in C:Help!!

    Perché usi [][] se hai dei vettori monodimensionali?

    Il vettore è rappresentato da un puntatore (ad esempio) a int: *v
    Tu hai un parametro con un doppio puntatore (ad esempio) a int: **v
    dovrai quindi dereferenziare il puntatore, quindi usare []: (*v)[indice]
    Così ottieni un certo int in **v.
    Siccome però in fscanf() ti serve un puntatore a int, il modo più immediatamente chiaro di ottenerlo è: &((*v)[indice])
    Un modo diverso per ottenere la stessa cosa è: (*v)+indice
    Dunque, fscanf(fp, "%d", (*mins)[0]); (che non va bene) può diventare fscanf(fp, "%d", (*mins)+i);

    L'esempio è su int, ma per float vale la stessa cosa.

    Comunque, ci sono anche altre "incongruenze" in quel che hai scritto.
  • Re: Esercizio in C:Help!!

    Sisi, sapevo che con la matrice così non sarebbe tornato.
    Per riempire i due vettori avrei potuto per caso usare due cicli for? Perchè quello che principalmente non riesco a capire è come faccia a sapere che il primo elemento della riga vada in un vettore e il secondo in un altro
  • Re: Esercizio in C:Help!!

    Quando leggi i dati da un file di testo, di solito li leggi in senso "lineare", uno dopo l'altro. Quindi, se il tuo file ha una struttura di questo tipo...

    4
    5 1.3
    3 9.3
    15 6.27
    8 3.2

    ...prima leggi il valore che ti dà la quantità delle righe coi dati, poi passi a leggere i valori successivi uno ad uno, o a coppie.

    Potresti quindi fare un singolo ciclo for (non due annidati) e ad ogni passaggio chiamare due volte fscanf() per ottenere un valore alla volta, oppure chiamare fscanf() una sola volta per ottenere due valori alla volta...
    // un valore per chiamata
    for( i=0; i<*nEl; i++ ) {
        fscanf(fp, "%d", (*mins)+i);
        fscanf(fp, "%f", (*maree)+i);
    }
    
    // oppure...
    
    // due valori per chiamata
    for( i=0; i<*nEl; i++ ) {
        fscanf(fp,"%d %f", (*mins)+i, (*maree)+i);
    }
    In entrambi i casi ti converrebbe verificare che fscanf() abbia letto come si deve i dati -- quando legge qualcosa restituisce la quantità degli elementi letti, quando non riesce a leggere niente restituisce EOF.
    // un valore per chiamata
    for( i=0; i<*nEl; i++ ) {
        if( 1!=fscanf(fp,"%d",(*mins)+i) ) {
            // errore! fai qualcosa!
        }
        
        if( 1!=fscanf(fp,"%f",(*maree)+i) ) {
            // errore! fai qualcosa!
        }
    }
    
    // oppure...
    
    // due valori per chiamata
    for( i=0; i<*nEl; i++ ) {
        if( 2!=fscanf(fp,"%d %f",(*mins)+i,(*maree)+i) ) {
            // errore! fai qualcosa!
        }
    }
  • Re: Esercizio in C:Help!!

    Ok magnifico, grazie mille davvero!
  • Re: Esercizio in C:Help!!

    Di niente. Ricordati di andare a caccia anche delle altre incongruenze, però!
  • Re: Esercizio in C:Help!!

    Il modo in cui ho fatto il malloc?
  • Re: Esercizio in C:Help!!

    Volendo, quello potrebbe essere un punto.

    a) in C non serve fare casting del void* restituito da malloc()
    b) dopo ogni chiamata a malloc(), calloc(), realloc()... conviene sempre verificare che non sia stato restituito NULL, ovvero che l'allocazione sia andata a buon fine

    Un'altra cosa che hai tralasciato, però, è il fatto che in caso d'errore prima di "ritornare" dovresti liberare con free() la memoria già allocata e annullare i puntatori corrispondenti. Inoltre, sempre, dovresti chiudere il file con fclose() quando non serve più tenerlo aperto -- se "ritorni" a metà funzione senza chiamare fclose() (e nel tuo codice succede), il file non viene chiuso.
  • Re: Esercizio in C:Help!!

    Ok , il discorso del free lo avevo inserito poi nel main, va bene lo stesso?
  • Re: Esercizio in C:Help!!

    Dipende da come fai le cose. Secondo me è meno pratico, ma io non sono un esperto.
  • Re: Esercizio in C:Help!!

    lauretta.3 ha scritto:


    Ok , il discorso del free lo avevo inserito poi nel main, va bene lo stesso?
    In genere le metti dove non ti serve più la memoria.
  • Re: Esercizio in C:Help!!

    Il mio riferimento era al fatto che in un vecchio libro sulla programmazione in Macintosh System 7 si insisteva sulla opportunità di essere dei "good citizens" in un sistema cooperativo. Uno dei capisaldi di quell'impostazione era: se una funzione fallisce, deve lasciare le cose come stavano PRIMA dell'invocazione alla funzione. Per questo il mio modo di procedere tende a essere quello per cui se una funzione fallisce NON lascia memoria allocata/parzialmente allocata.

    In questo caso, se non riesco a leggere per intero e in modo affidabile i dati nel file, non lascio al chiamante la responsabilità di liberare memoria, chiudere file e così via.

    E' una buona cosa? E' una cattiva cosa? Boh... Diciamo che è una mia mania.
Devi accedere o registrarti per scrivere nel forum
11 risposte