FILE in C

nickronaldo7
Salve a tutti ho un esercizio da fare con i file.
Praticamente in questo esercizio mi viene detto che non si conosce la lunghezza del file, pertanto non posso salvarlo in un vettore(non posso usare memoria dinamica!).
Dunque ora mi chiedo se esiste un modo per leggere il file per righe senza salvarlo in delle variabiali ??
Se è necessario posto il testo dell'esercizio :)

Risposte
el_brando
Un file lo puoi leggere anche un carattere alla volta !
Quindi puoi anche leggere un numero prestabilito di caratteri alla volta dal file e salvarli in un array statico debitamente dimensionato...

vict85
"nickronaldo7":
[...](non posso usare memoria dinamica!).

Falso. Quello che non puoi farlo è inzializzare la memoria dinamica in anticipo.

"nickronaldo7":
Dunque ora mi chiedo se esiste un modo per leggere il file per righe senza salvarlo in delle variabiali ??
Se è necessario posto il testo dell'esercizio :)

Più che leggerlo il tuo problema penso sia memorizzarlo, ma non è detto che serva farlo. Molto dipende da cosa devi farci.

nickronaldo7
"vict85":
[quote="nickronaldo7"][...](non posso usare memoria dinamica!).

Falso. Quello che non puoi farlo è inzializzare la memoria dinamica in anticipo.

"nickronaldo7":
Dunque ora mi chiedo se esiste un modo per leggere il file per righe senza salvarlo in delle variabiali ??
Se è necessario posto il testo dell'esercizio :)

Più che leggerlo il tuo problema penso sia memorizzarlo, ma non è detto che serva farlo. Molto dipende da cosa devi farci.[/quote]

perfetto, la seconda risposta era quella che cercavo, infatti cercavo di salvare il file in una struct, cosa impossibile non conoscendo la dimensione! Comunque mi sono espresso male nel dire che non posso usare la memoria dinamica. So che si può ma è il nostro prof a non farcela usare.

vict85
Certo, il punto è che se ci dici che cosa devi calcolare possiamo consigliarti meglio.

nickronaldo7
il programma è questo:
Si desidera sviluppare un programma (in linguaggio C) per calcolare l’incasso di un evento sportivo relativo ai
biglietti venduti.
I biglietti venduti sono registrati in un file, uno per riga col seguente formato:
• data delle vendita nel formato AAAAMMGG (es. 20120522 per indicare il 22/5/2012);
• l’ora della vendita, nel formato HHMM (es. 1849 per indicare le 18:49);
• settore dello stadio, indicato da un numero intero positivo;
• posto all’interno del settore, composto dalla fila (indicata da un carattere alfabetico maiuscolo compreso
tra A e Z) e dal posto nella fila (indicato da un numero intero positivo).
Il prezzo di un biglietto `e diverso per ciascun settore. I prezzi sono indicati nel file settori.txt in cui ogni
riga ha il seguente formato:
• settore dello stadio, indicato da un numero intero compresso tra 1 e 10;
• prezzo in Euro, espresso come numero positivo con due cifre frazionarie.
In questo file sono presenti solo i settori aperti per l’evento in oggetto. Tutti gli altri settori non elencati sono
considerati chiusi e non si possono vendere biglietti per essi.
Il programma riceve sulla riga di comando il nome del file contenente l’elenco dei biglietti venduti e deve
calcolare il numero totale di biglietti venduto ed il corrispondente ricavo.
Nel caso che l’elenco contenga un biglietto corrispondente ad un settore non in vendita per l’evento in oggetto
(ossia un settore non presente nel file settori.txt) deve essere generata una segnalazione di errore ed il
biglietto in oggetto deve essere scartato dal calcolo del ricavo.
Esempio. Si consideri il file nba.txt con il seguente contenuto:
20120518 0910 1 B33
20120518 0925 2 A12
20120518 1020 4 A4
20120519 0640 2 H34
mentre il file settori.txt contiene:
2 49.99
1 100.00
3 9.50
Se il programma (denominato vendita) venisse attivato come
vendita nba.txt
allora il programma dovrebbe produrre in output:
*** errore: biglietto settore 4 posto A4 per settore non in vendita
- biglietti venduti: 3
- ricavo: 199.98 Euro


io ho provato a scrivere tale codice ma non funziona il doppio ciclo while(si ferma solo al primo) non so il perché puoi aiutarmi :?:

#include <stdio.h>
#include <stdlib.h>

int main()
{
    FILE *f,*g;
    char data[9];
    char ora[5];
    int set,i=0;
    char interno_settore[4];
    int settore_stadio;
    float prezzo,somma=0;

    if((f=fopen("nba.txt","r"))==NULL)
        return -1;
    if((g=fopen("settori.txt","r"))==NULL)
        return -2;

         while((fscanf(f,"%s %s %d %s", data,ora,&set,interno_settore))!=EOF)
{
             while((fscanf(g,"%d %f", &settore_stadio,&prezzo))!=EOF)
            {
                if(set==settore_stadio)
                            {
                                somma=somma+prezzo;
                                                i++;
                            }
            }
}
printf("\nbiglietti venduti: %d",i);
printf("\nricavo: %.2f euro", somma);
fclose(f);fclose(g);
    return 0;
}

vict85
Il valore di ritorno di fscanf è un intero ed è uguale al numero di elementi assegnati con successo oppure è EOF che è un numero negativo. Sarebbe quindi appropriato usare delle condizioni del tipo
while( fscanf(f,"%s %s %d %s", data,ora,&set,interno_settore) == 4 )
e
while(fscanf(g,"%d %f", &settore_stadio,&prezzo)==2)
Ma questa è una sottigliezza.

Il problema del tuo codice è che per funzionare dovresti rileggere in continuazione settori.txt ma non ritorni mai all'inizio del file. Perciò immagino che un correzione semplice del tipo:
while(fscanf(f,"%s %s %d %s", data,ora,&set,interno_settore)==4)
{
             while( fscanf(g,"%d %f", &settore_stadio,&prezzo)==2 )
            {
                if(set==settore_stadio)
                            {
                                somma=somma+prezzo;
                                                i++;
                            }
            }
            rewind(g);
}
dovrebbe correggere l'errore in questione seppur non direi che è un metodo ottimale.

Un metodo migliore leggerebbe settori.txt e memorizzerebbe il valore in un array di float (potresti usare per esempio -1.0f per segnare quando un elemento non è presente in settori dato che i prezzi sono positivi). Dopo di che leggerebbe il file nba.txt controllando le varie cose.

È evidente che un programma più serio controllerebbe che settori non abbia ripetizioni e che in nba non sia stato venduto lo stesso posto due volte.

nickronaldo7
"vict85":
Il valore di ritorno di fscanf è un intero ed è uguale al numero di elementi assegnati con successo oppure è EOF che è un numero negativo. Sarebbe quindi appropriato usare delle condizioni del tipo
while( fscanf(f,"%s %s %d %s", data,ora,&set,interno_settore) == 4 )
e
while(fscanf(g,"%d %f", &settore_stadio,&prezzo)==2)
Ma questa è una sottigliezza.

Il problema del tuo codice è che per funzionare dovresti rileggere in continuazione settori.txt ma non ritorni mai all'inizio del file. Perciò immagino che un correzione semplice del tipo:
while(fscanf(f,"%s %s %d %s", data,ora,&set,interno_settore)==4)
{
             while( fscanf(g,"%d %f", &settore_stadio,&prezzo)==2 )
            {
                if(set==settore_stadio)
                            {
                                somma=somma+prezzo;
                                                i++;
                            }
            }
            rewind(g);
}
dovrebbe correggere l'errore in questione seppur non direi che è un metodo ottimale.


Ok si sapevo che la fscanf ritorna un intero il problema è che io non so il numero di biglietti quello è solo un esempio, infatti potrei avere un altro txt con un numero diverso da 4 biglietti...

apatriarca
Ma la stringa di formato è sempre la stessa per ogni riga. fscanf restituirà quindi sempre un valore tra 0 e 4 corrispondente al numero di valori letti correttamente in quella riga. Volendo però effettivamente verificare che i valori siano scritti in righe separate il metodo corretto sarebbe quello di leggere una singola riga con fgets e poi usare sscanf per leggere i valori.

nickronaldo7
"apatriarca":
Ma la stringa di formato è sempre la stessa per ogni riga. fscanf restituirà quindi sempre un valore tra 0 e 4 corrispondente al numero di valori letti correttamente in quella riga. Volendo però effettivamente verificare che i valori siano scritti in righe separate il metodo corretto sarebbe quello di leggere una singola riga con fgets e poi usare sscanf per leggere i valori.


Ah giusto non avevo capito il valore di 4 e 2, comunque andando a sostituire nel codice mi rifà sempre lo stesso "errore" :lol:

nickronaldo7
aggiornamento: ho provato anche con la fgets e sscanf ma mi torna sempre la stessa cosa

vict85
Ma hai aggiunto il rewind(g) ?

nickronaldo7
"vict85":
Ma hai aggiunto il rewind(g) ?


mi era sfuggito..potresti spiegarmi come funziona?? ho un libro di c ma non l'ho mai incontrato fino ad ora.
comunque il programma funziona :)

vict85
Il file viene letto in modo consecutivo, ogni nuovo fscanf, fgets... porta avanti il puntatore. rewind è la funzione C che riporta il puntatore all'inizio del file. http://en.cppreference.com/w/c/io/rewind

Rispondi
Per rispondere a questa discussione devi prima effettuare il login.