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!
![]() ![]() |
26 May 2005, 11:48
Messaggio
#1
|
|
|
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 |
|
|
|
|
|
|
|
27 May 2005, 06:40
Messaggio
#2
|
|
|
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
-------------------- |
|
|
|
|
27 May 2005, 07:00
Messaggio
#3
|
|
|
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 -------------------- Marco Coïsson
http://web.me.com/marco_coisson L'atomo divisibile: podcast gratuito di divulgazione scientifica. X come Macintosh |
|
|
|
|
27 May 2005, 23:15
Messaggio
#4
|
|
|
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 io avevo dovuto cimentarmi nella lettura/scrittura binaria e facendo la conversione bigendian/littleendian quando dovevo lavorare con network simulator... bei ricordi.... -------------------- |
|
|
|
|
![]() ![]() |
Argomenti simili o correlati
| Titolo discussione | Risposte | Autore discussione | Visite | Ultima azione | |||
|---|---|---|---|---|---|---|---|
![]() |
4 | senza_speranza | 80 | Oggi, 10:20 Ultimo messaggio di: [Daitarn] |
|||
![]() |
2 | gerod | 77 | 5 February 2010 - 15:09 Ultimo messaggio di: Martini |
|||
![]() |
3 | ilbagatta | 166 | 29 January 2010 - 00:01 Ultimo messaggio di: ilbagatta |
|||
![]() |
9 | ilgio | 260 | 28 January 2010 - 16:51 Ultimo messaggio di: blueknight |
|||
![]() |
3 | fac | 223 | 19 January 2010 - 12:10 Ultimo messaggio di: [Daitarn] |
|||
![]() |
7 | arbushell | 190 | 15 January 2010 - 20:35 Ultimo messaggio di: cristianof |
|||
![]() |
9 | gianky53 | 281 | 5 January 2010 - 18:22 Ultimo messaggio di: il Mac-eretico |
|||
![]() |
3 | gianky53 | 149 | 26 December 2009 - 20:38 Ultimo messaggio di: cenomans |
|||
![]() |
3 | morellino | 286 | 27 November 2009 - 10:05 Ultimo messaggio di: morellino |
|||
![]() |
1 | ryosaeb4 | 121 | 15 November 2009 - 17:29 Ultimo messaggio di: chebfarid |
|||
![]() |
3 | kabaci | 179 | 14 November 2009 - 18:40 Ultimo messaggio di: chebfarid |
|||
![]() |
2 | c1p8 | 228 | 12 November 2009 - 17:18 Ultimo messaggio di: the_devil_88 |
|||
|
Versione Lo-Fi | Oggi è il: 9 February 2010 - 15:02 |
| IP.Board Skin Developed By Creative Networks | ||