IPB     Una pizza e una birra...
Hai risolto dei problemi sul tuo Mac grazie a questo forum? Offrici una pizza..

Benvenuto su Tevac ( Log In | Registrati )
Tevac è una allegra combriccola di amici, alcuni appassionati di Mac, altri di Fotografia, o di entrambi.
Partecipa, dai vita a questa community, condividi le tue esperienze!
Non aver paura di iniziare una discussione o di rispondere ad un amico che cerca aiuto!

 Condividi questo topic su Digg · Condividi questo topic su del.icio.us · Condividi questo topic su Slashdot · Condividi questo topic su Technorati · Condividi questo topic su Furl · Condividi questo topic su Reddit · Condividi questo topic su Facebook · Condividi questo topic su Fark · Condividi questo topic su Google · Condividi questo topic su ma.gnolia · Condividi questo topic su Wink · Condividi questo topic su MyWeb · Condividi questo topic su Netscape
Reply to this topicStart new topic
> [C] - Tutorial I/O da file
Marco Coïsson
messaggio 26 May 2005, 11:48
Messaggio #1


life, n: a whim of several billion cells to be you for a while
***********

Gruppo: Forum User +
Messaggi: 9.340
Iscritto il: 18-May 03
Da: Torino
Utente Nr.: 65



In questo brevissimo tutorial vediamo come si possa, usando il C standard, leggere e scrivere file di testo. È richiesta una conoscenza minimale del C.

1. Quando già si sa quali file leggere e scrivere
In questo primo codice di esempio assumiamo di conoscere già quali file vorremo leggere e scrivere; il loro nome (ed eventualmente il percorso) verranno pertanto inclusi direttamente nel codice sorgente del programma. Si tratta del caso più semplice, e pertanto lo esaminiamo per primo.
Aprite il vostro editor di testo preferito e digitate il seguente programma:
CODICE
#include <stdio.h>

#include <stdlib.h>



#define kFileDaLeggere          "input.txt"

#define kFileDaScrivere         "output.txt"

#define kLunghezzaMaxStringa    100



#define kErroreIO               -1

#define kErroreMemoria          -2

#define kNessunErrore           0



double      numero1,numero2,numero3;

char        *stringa;



int main (void);

int LeggiDaFile(void);

int ScriviSuFile(void);



int main (void)

{

   int         errore;

   

   errore=LeggiDaFile();

   if(errore)

       return errore;

   errore=ScriviSuFile();

   if(errore)

       return errore;

   

   return kNessunErrore;

}



int LeggiDaFile(void)

{

   FILE        *ingresso;

   

   printf("Lettura dal file %sn",kFileDaLeggere);

   ingresso=fopen(kFileDaLeggere,"r");

   if(ingresso==NULL)

       return kErroreIO;

   stringa=calloc(kLunghezzaMaxStringa,sizeof(char));

   if(stringa==NULL)

       return kErroreMemoria;

   fscanf(ingresso,"%lg %lg %lg %s",&numero1,&numero2,&numero3,stringa);

   printf("Numero 1: %gnNumero 2: %gnNumero 3: %gnStringa: %sn",numero1,numero2,numero3,stringa);

   printf("n");

   fclose(ingresso);

   

   return kNessunErrore;

}



int ScriviSuFile(void)

{

   FILE        *uscita;

   

   printf("Scrittura sul file %sn",kFileDaScrivere);

   uscita=fopen(kFileDaScrivere,"w");

   if(uscita==NULL)

       return kErroreIO;

   fprintf(uscita,"%g %g %g %sn",numero1,numero2,numero3,stringa);

   printf("Ora puoi aprire il file %s e verificare che contenga una copia di %sn",kFileDaScrivere,kFileDaLeggere);

   printf("n");

   return kNessunErrore;

}

Salvatelo come demoIO.c. Sempre col vostro editor di testo preferito, create anche un nuovo file, che salverete come input.txt nella stessa cartella in cui avete salvato demoIO.c, che abbia il seguente contenuto:
CODICE
25.14 33.75 -3.14e24 Teodorico

Aprite il Terminale e recatevi nella cartella in cui avete salvato i due file. Compilate il programma col comando
CODICE
gcc -o demoIO demoIO.c

Se non ci sono errori, eseguitelo col comando
CODICE
./demoIO

Osservate che l'output dovrebbe essere simile a questo:
CODICE
Lettura dal file input.txt

Numero 1: 25.14

Numero 2: 33.75

Numero 3: -3.14e+24

Stringa: Teodorico



Scrittura sul file output.txt

Ora puoi aprire il file output.txt e verificare che contenga una copia di input.txt

Dal Finder, aprite il file output.txt che è stato creato nella stessa cartella in cui avete salvato gli altri due, e verificate che contiene esattamente quello che conteneva input.txt.
Come è avvenuto tutto questo? Esaminiamo il codice nel dettaglio.
I nomi dei file di ingresso e di uscita sono memorizzati a livello di codice nelle due costanti kFileDaLeggere e kFileDaScrivere. Notate che i file vanno specificati col loro percorso; in assenza di questo, il programma li cerca o li colloca nella stessa cartella in cui si trova l'eseguibile; in alternativa, dovete specificare il nome del file con un percorso relativo alla cartella in cui si trova l'eseguibile o assoluto.
Quattro variabili globali (numero1, numero2, numero3 e stringa) saranno deputate a conservare il contenuto del file di input così da poterlo riscrivere nel file di output.
Le funzioni che si occupano di leggere e scrivere i file sono ovviamente LeggiDaFile() e ScriviSuFile(). La prima apre il file di ingresso mediante la funzione fopen(). Essa vuole come primo argomento il nome del file da aprire (con il suo percorso, relativo o assoluto), e come secondo argomento un parametro che specifica come vada aperto il file. Qui specifichiamo "r", che indica che il file va aperto in lettura (reading). Discuteremo più avanti degli altri parametri disponibili. Se il file viene correttamente trovato ed aperto, la variabile ingresso di tipo puntatore a FILE contiene un riferimento al file specificato; se no contiene il valore NULL, che può essere controllato per verificare se ci sono stati errori.
La lettura dal file si fa con una funzione assolutamente analoga a scanf() di nome fscanf(); l'unica differenza è che fscanf() anziché leggere dallo standard input (ovvero dalla tastiera) legge dal file specificato come primo argomento; il secondo argomento individua il formato di ciò che si va a leggere, e a seguire ci sono i puntatori alle variabili in cui verranno inseriti i contenuti del file. A parte il primo argomento (il puntatore al file), l'uso di fscanf() è assolutamente identico all'uso di scanf(), e alla documentazione su quest'ultima si rimanda il lettore.
Il file viene quindi chiuso con una chiamata a fclose().
La scrittura sul file si effettua un modo assolutamente analogo, le uniche differenze essendo il parametro da passare a fopen() (ora gli passiamo "w" per indicare la scrittura su file, o writing), e la funzione usata per la scrittura dei contenuti dei file: fprintf(), identica a printf() nell'uso (e ancora una volta rimandiamo il lettore alla documentazione su printf() per il dettaglio della sintassi) con la sola differenza che richiede, come primo argomento, il puntatore al file di uscita.

2. Quando ancora non si sa quali file leggere e scrivere
È possibile che in sede di scrittura del programma ancora non si sappia quali file verranno letti o scritti; tale scelta sarà infatti rinviata in fase di runtime. In questo caso non è possibile includere il nome del file e il suo percorso direttamente nel codice del programma, ma è meglio lasciare che sia l'utente a specificare su quali file intende agire. È naturalmente possibile prevedere una funzione del programma che chiede all'utente di immettere nome e percorso dei file di ingresso e di uscita, ma è possibile anche un'altra strada che esaminiamo qui brevemente: specificare i nomi dei file di interesse direttamente quando si lancia il programma tramite il Terminale.
Aprite il vostro editor di testo preferito e digitate il seguente codice, che è una variante di quello precedente:
CODICE
#include <stdio.h>

#include <stdlib.h>



#define kLunghezzaMaxStringa    100



#define kErroreIO               -1

#define kErroreMemoria          -2

#define kErroreArgomenti        -3

#define kNessunErrore           0



double      numero1,numero2,numero3;

char        *stringa;



int main (int argc, char *argv[]);

int LeggiDaFile(char *fin);

int ScriviSuFile(char *fout);



int main (int argc, char *argv[])

{

   int         errore;

   

   if(argc != 3)

   {

       printf("Devi specificare un file di ingresso e uno di uscita!n");

       return kErroreArgomenti;

   }

   errore=LeggiDaFile(argv[1]);

   if(errore)

       return errore;

   errore=ScriviSuFile(argv[2]);

   if(errore)

       return errore;

   

   return kNessunErrore;

}



int LeggiDaFile(char *fin)

{

   FILE        *ingresso;

   

   printf("Lettura dal file %sn",fin);

   ingresso=fopen(fin,"r");

   if(ingresso==NULL)

       return kErroreIO;

   stringa=calloc(kLunghezzaMaxStringa,sizeof(char));

   if(stringa==NULL)

       return kErroreMemoria;

   fscanf(ingresso,"%lg %lg %lg %s",&numero1,&numero2,&numero3,stringa);

   printf("Numero 1: %gnNumero 2: %gnNumero 3: %gnStringa: %sn",numero1,numero2,numero3,stringa);

   printf("n");

   fclose(ingresso);

   

   return kNessunErrore;

}



int ScriviSuFile(char *fout)

{

   FILE        *uscita;

   

   printf("Scrittura sul file %sn",fout);

   uscita=fopen(fout,"w");

   if(uscita==NULL)

       return kErroreIO;

   fprintf(uscita,"%g %g %g %sn",numero1,numero2,numero3,stringa);

   printf("Ora puoi aprire il file %s.n",fout);

   printf("n");

   return kNessunErrore;

}

Salvatelo come demoIOargomenti.c. Nella stessa cartella accertatevi che ci sia il file di testo input.txt già creato in precedenza, e abbiate cura di cancellare il file output.txt. Compilate il programma col comando
CODICE
gcc -o demoIOargomenti demoIOargomenti.c

ed eseguitelo col comando
CODICE
./demoIOargomenti input.txt output.txt

Osservate che nella cartella in cui si trova il programma viene creato il file output.txt, che come prima contiene una copia del file input.txt.
Le funzioni di lettura da e di scrittura su file sono sempre le stesse, semplicemente abbiamo sfruttato la possibilità offerta dal C di ricevere degli argomenti nella funzione main(), argomenti che vengono specificati dall'utente all'atto di eseguire il programma. La funzione main() infatti ha ora due argomenti. Il primo, argc di tipo int, contiene il numero di argomenti specificati dall'utente quando ha eseguito il programma; essa vale sempre almeno 1, in quanto il primo argomento è sempre il nome del programma stesso. Il secondo, argv[], è un'array di puntatori a char (ovvero un'array di stringhe), e contiene (sotto forma di stringhe per l'appunto) i vari argomenti passati dall'utente al programma. Nel nostro caso, il programma richiede che l'utente specifichi esattamente e in quest'ordine un solo file di ingresso e un solo file di uscita, quindi argc deve valere 3 (nome del programma, file di ingresso, file di uscita) e l'array argv[] conterrà, in corrispondenza degli indici 0, 1 e 2 rispettivamente il nome del programma, il nome del file di ingresso e il nome del file di uscita. Questi ultimi due vengono passati ad argomento a LeggiDaFile() e a ScriviSuFile().

3. Osservazioni
[list] il programma restituirà un errore o si comporterà in maniera imprevedibile.
[*]È naturalmente possibile acquisire il contenuto di un file privo di un formato specifico memorizzandolo interamente all'interno di una stringa (sempre da acquisire con fscanf()) e rinviando ad un secondo momento l'esame del contenuto della stringa al fine di estrarne le informazioni contenute (parsing).
[*]In luogo di fscanf() è possibile usare le funzioni
[list] un solo carattere e lo restituisce
[*]char *fgets(char *s,int n,FILE *ingresso) che legge n caratteri da ingresso e li copia in s (e li restituisce)
[list]
[*]Per la lettura da file sono inoltre disponibili altre funzioni, come fread(), fgetpos(), fsetpos(), feof() che vanno al di là dello scopo di questo tutorial.
[*]Similmente, la scrittura su file può essere fatta mediante funzioni alternative a fprintf(), quali ad esempio:
[list]
[*]int fputs(char *s,FILE *uscita) che scrive la stringa contenuta in s nel file uscita[list]
[*]Anche per la scrittura su file, funzioni più complesse come fwrite() sono disponibili ma esulano dallo scopo di questo tutorial.[list]

4. I parametri di fopen()
Qui di seguito sono indicati i parametri che, racchiusi tra virgolette, possono essere passati a fopen() per specificare la modalità con cui andrà aperto il file:
[list] - il file viene aperto in sola lettura
[*]w - il file viene aperto in scrittura; se un file con lo stesso nome esisteva già, viene cancellato
[*]a - il file viene aperto in scrittura; se un file con lo stesso nome esisteva già, il nuovo contenuto viene aggiunto al fondo del contenuto vecchio, che non viene cancellato
[*]rb - come r, ma il file è binario
[*]wb - come w, ma il file è binario
[*]ab - come a, ma il file è binario
[*]r+ - il file viene aperto in lettura e scrittura; se un file con lo stesso nome esisteva già, il contenuto precedente non viene cancellato
[*]w+ - il file viene aperto in lettura e scrittura; se un file con lo stesso nome esisteva già, il contenuto precedente viene cancellato
[*]a+ - il file viene aperto in lettura e scrittura; se un file con lo stesso nome esisteva già, il contenuto precedente non viene cancellato, ma tutte le operazioni di lettura e scrittura avvengono al termine del file, in coda al contenuto precedente
[*]r+b oppure rb+ - come r+, ma il file è binario
[*]w+b oppure wb+ - come w+, ma il file è binario
[*]a+b oppure ab+ - come a+, ma il file è binario
[list]
Buon divertimento! : )


--------------------
Marco Coïsson
http://web.me.com/marco_coisson

L'atomo divisibile: podcast gratuito di divulgazione scientifica.

X come Macintosh
Go to the top of the page
 
+Quote Post
iceman314
messaggio 27 May 2005, 06:40
Messaggio #2


Level 1/11
*

Gruppo: Forum User
Messaggi: 31
Iscritto il: 15-October 04
Da: Pavia
Utente Nr.: 2.516



nulla da dire... pur guardando il tuo tutorial velocemente, sei stato molto preciso... il prossimo tutorial per la scrittura lettura binaria con fread e fwrite icon_wink.gif


--------------------
Go to the top of the page
 
+Quote Post
Marco Coïsson
messaggio 27 May 2005, 07:00
Messaggio #3


life, n: a whim of several billion cells to be you for a while
***********

Gruppo: Forum User +
Messaggi: 9.340
Iscritto il: 18-May 03
Da: Torino
Utente Nr.: 65



CITAZIONE(iceman314)
il prossimo tutorial per la scrittura lettura binaria con fread e fwrite  :wink:

Ah, questa la vedo più dura: non l'ho mai fatto prima, devo studiare icon_wink.gif icon_biggrin.gif


--------------------
Marco Coïsson
http://web.me.com/marco_coisson

L'atomo divisibile: podcast gratuito di divulgazione scientifica.

X come Macintosh
Go to the top of the page
 
+Quote Post
iceman314
messaggio 27 May 2005, 23:15
Messaggio #4


Level 1/11
*

Gruppo: Forum User
Messaggi: 31
Iscritto il: 15-October 04
Da: Pavia
Utente Nr.: 2.516



CITAZIONE(marcocoisson)
CITAZIONE(iceman314)
il prossimo tutorial per la scrittura lettura binaria con fread e fwrite  :wink:

Ah, questa la vedo più dura: non l'ho mai fatto prima, devo studiare icon_wink.gif icon_biggrin.gif

io avevo dovuto cimentarmi nella lettura/scrittura binaria e facendo la conversione bigendian/littleendian quando dovevo lavorare con network simulator... bei ricordi.... icon_rolleyes.gif


--------------------
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic

 

Collapse

> Argomenti simili o correlati

    Titolo discussione Risposte Autore discussione Visite Ultima azione
No New Posts   4 senza_speranza 80 Oggi, 10:20
Ultimo messaggio di: [Daitarn]
No New Posts   2 gerod 77 5 February 2010 - 15:09
Ultimo messaggio di: Martini
No New Posts   3 ilbagatta 166 29 January 2010 - 00:01
Ultimo messaggio di: ilbagatta
No new   9 ilgio 260 28 January 2010 - 16:51
Ultimo messaggio di: blueknight
No New Posts   3 fac 223 19 January 2010 - 12:10
Ultimo messaggio di: [Daitarn]
No New Posts   7 arbushell 190 15 January 2010 - 20:35
Ultimo messaggio di: cristianof
No new   9 gianky53 281 5 January 2010 - 18:22
Ultimo messaggio di: il Mac-eretico
No New Posts   3 gianky53 149 26 December 2009 - 20:38
Ultimo messaggio di: cenomans
No New Posts   3 morellino 286 27 November 2009 - 10:05
Ultimo messaggio di: morellino
No New Posts   1 ryosaeb4 121 15 November 2009 - 17:29
Ultimo messaggio di: chebfarid
No New Posts   3 kabaci 179 14 November 2009 - 18:40
Ultimo messaggio di: chebfarid
No New Posts   2 c1p8 228 12 November 2009 - 17:18
Ultimo messaggio di: the_devil_88

Modalità di visualizzazione: Normale · Passa a: Lineare · Passa a: Outline


RSS Versione Lo-Fi Oggi è il: 9 February 2010 - 15:02
IP.Board Skin Developed By Creative Networks