Articolo originale: https://www.freecodecamp.org/news/file-handling-in-c-how-to-open-close-and-write-to-files/
Se in precedenza hai già scritto il programma C helloworld
, conosci già le basi dell'I/O dei file in C:
/* Un semplice hello world in C. */
#include <stdlib.h>
// Importa funzioni I/O.
#include <stdio.h>
int main() {
// Questo printf è dove avviene tutta la magia IO del file!
// Che emozione!
printf("Hello, world!\n");
return EXIT_SUCCESS;
}
La gestione dei file è una delle parti più importanti della programmazione. In C, utilizziamo un puntatore a una struttura di tipo file per dichiarare un file:
FILE *fp;
C fornisce una serie di funzioni integrate per eseguire operazioni di base sui file:
fopen()
- crea un nuovo file o apri un file esistentefclose()
- chiude un filegetc()
- legge un carattere da un fileputc()
- scrive un carattere in un filefscanf()
- legge un insieme di dati da un filefprintf()
- scrive un insieme di dati in un filegetw()
- legge un numero intero da un fileputw()
- scrive un numero intero in un filefseek()
- imposta la posizione sul punto desideratoftell()
- fornisce la posizione corrente nel filerewind()
- imposta la posizione al punto iniziale
Apertura di un file
La funzione fopen()
viene utilizzata per creare un file o aprire un file esistente:
fp = fopen(const char nomefile,const char modalità);
Ci sono molte modalità per aprire un file:
r
- aprire un file in modalità letturaw
- apre o crea un file di testo in modalità scritturaa
- apre un file in modalità "aggiungi"r+
- apre un file sia in lettura che in scritturaa+
- apre un file sia in lettura che in scritturaw+
- apre un file sia in lettura che in scrittura
Ecco un esempio di lettura di dati da un file e di scrittura su di esso:
#include<stdio.h>
#include<conio.h>
main()
{
FILE *fp;
char ch;
fp = fopen("hello.txt", "w");
printf("Inserisci il dato: ");
while( (ch = getchar()) != EOF) {
putc(ch,fp);
}
fclose(fp);
fp = fopen("hello.txt", "r");
while( (ch = getc(fp)! = EOF)
printf("%c",ch);
fclose(fp);
}
Ora potresti pensare: "Questo stampa solo il testo sullo schermo. Come fa a essere IO su file?"
La risposta non è così ovvia all'inizio e richiede una certa comprensione del sistema UNIX. In un sistema UNIX, tutto viene trattato come un file, il che vuol dire che puoi leggere e scrivere su di esso.
Quindi anche il tuo printer può essere astratto ad un file poiché quello che fai con un printer è scrivere con esso. È anche utile pensare a questi file come flussi, poiché come vedrai in seguito, puoi reindirizzarli con la shell.
Quindi, come si collega questo a helloworld
e all'IO sui file?
Quando si chiama printf
, in realtà si sta semplicemente scrivendo su un file speciale chiamato stdout
, abbreviazione di standard output . stdout
rappresenta l'output standard come deciso dalla tua shell, che di solito è il terminale. Questo spiega perché è stato stampato sullo schermo.
Ci sono altri due flussi (es. file) che sono disponibili per te con un certo impegno, stdin
e stderr
. stdin
rappresenta lo standard input, che la tua shell di solito collega alla tastiera. stderr
rappresenta l'output di errore standard , che la tua shell di solito lega al terminale.
IO rudimentale su File
Basta teoria, mettiamoci al lavoro scrivendo del codice! Il modo più semplice per scrivere su un file è reindirizzare il flusso di output utilizzando lo strumento di reindirizzamento dell'output, >
.
Se vuoi effettuare una aggiunta alla fine del file, puoi usare >>
:
# Questo stamperà sullo schermo...
./helloworld
# ...ma questo scriverà nel file!
./helloworld > hello.txt
Il contenuto di hello.txt
, non a caso, sarà
Hello, world!
Supponiamo di avere un altro programma chiamato greet
, simile a helloworld
, che ti saluta con un dato name
:
#include <stdio.h>
#include <stdlib.h>
int main() {
// Inizializza un array per contenre il nome.
char nome[20];
// Leggi la stringa e salvala in nome.
scanf("%s", nome);
// Print the greeting.
printf("Ciao, %s!", nome);
return EXIT_SUCCESS;
}
Invece di leggere dalla tastiera, possiamo reindirizzare stdin
alla lettura da un file utilizzando lo strumento <
:
# Scrivi un file contenente un nome.
echo Kamala > name.txt
# Questo leggerà il nome dal file e stamperà il saluto sullo schermo.
./greet < name.txt
# ==> Ciao, Kamala!
# Se vuoi anche scrivere il saluto su un file, puoi farlo usando ">".
Nota: questi operatori di reindirizzamento sono simili in bash
e shell.
Il vero affare
I metodi di cui sopra funzionano solo per i casi più elementari. Se vuoi fare cose più complicate e fatte meglio, probabilmente dovrai lavorare con i file all'interno di C invece che attraverso la shell.
Per fare ciò, utilizzerai una funzione chiamata fopen
. Questa funzione accetta due parametri stringa, il primo è il nome del file e il secondo è la modalità.
Le modalità sono fondamentalmente delle autorizzazioni, quindi r
per leggere, w
scrivere, a
aggiungere. Puoi anche combinarli, quindi rw
significa che potresti leggere e scrivere sul file. Ci sono più modalità, ma queste sono quelle più comunemente usate.
Dopo aver ottenuto un puntatore FILE
, puoi utilizzare praticamente gli stessi comandi IO che hai già usato, tranne per il fatto che devi anteporre loro una f
e il primo argomento sarà il puntatore del file. Ad esempio, la versione per i file di printf
è fprintf
.
Ecco un programma chiamato greetings
che legge dati da un file contenente un elenco di nomi e scrive i saluti in un altro file:
#include <stdio.h>
#include <stdlib.h>
int main() {
// Crea i puntatori ai file.
FILE *names = fopen("names.txt", "r");
FILE *greet = fopen("greet.txt", "w");
// Controlla che tutto sia OK.
if (!names || !greet) {
fprintf(stderr, "Apertura del file fallita!\n");
return EXIT_FAILURE;
}
// Tempo di saluti!
char nome[20];
// Fondamentalmente continua a leggere finché non rimane più niente.
while (fscanf(names, "%s\n", nome) > 0) {
fprintf(greet, "Ciao, %s!\n", nome);
}
// Una volta raggiunta la fine, stampa un messaggio sul terminale per informare l'utente.
if (feof(names)) {
printf("I saluti sono terminati!\n");
}
return EXIT_SUCCESS;
}
Supponiamo che names.txt
contenga quanto segue:
Kamala
Logan
Carol
Quindi dopo aver eseguito greetings
il file greet.txt
conterrà:
Ciao, Kamala!
Ciao, Logan!
Ciao, Carol!