HOWTO · C++
Come scrivere in un file in C++
Questo articolo mostra come scrivere in un file in C++. Scopri gli stream di file e le diverse modalità di apertura, e guarda esempi chiari per gestire in modo efficace le operazioni sui file nei tuoi programmi C++. Che tu debba aggiungere dati o sovrascrivere il contenuto esistente, questa guida fa al caso tuo.
In questa pagina
Per scrivere testo normale in un file, usa std::ofstream con l’operatore di inserimento (<<). Apri il file con std::ios::app per aggiungere i dati in fondo, oppure usa std::ios::trunc per sostituire il contenuto esistente. Se conosci il numero di caratteri o byte da scrivere, usa la funzione membro write di uno stream; fwrite è l’alternativa corrispondente nello stile C.
Capire gli stream di file in C++
Gli stream di file collegano un programma C++ a un file identificato da un nome. Includi <fstream> e crea uno std::ofstream per scrivere; usa std::fstream quando lo stesso stream deve consentire sia la lettura sia la scrittura. L’operatore di inserimento è comodo per il testo formattato, e un carattere di nuova riga nella stringa avvia una nuova riga nel file. Controlla lo stato dello stream dopo l’apertura e la scrittura: un percorso apparentemente valido potrebbe non essere accessibile oppure lo spazio di archiviazione potrebbe non essere disponibile.
Esegui questo esempio:
#include <fstream>
#include <iostream>
int main() {
std::ofstream file("example.txt");
if (!file) {
std::cerr << "Could not open example.txt\n";
return 1;
}
file << "Hello, C++!\n";
file << "File output is ready.\n";
file.close();
if (!file) {
std::cerr << "Could not finish writing example.txt\n";
return 1;
}
std::cout << "Wrote example.txt\n";
return 0;
}
Wrote example.txt
Il messaggio viene stampato nella console; le due righe scritte tramite file vengono salvate in example.txt. Apri il file con un editor di testo per verificarne il contenuto. Uno std::ofstream aperto in modalità di sola scrittura crea il file se la directory genitore esiste e, di norma, ne cancella il contenuto precedente all’apertura.
Scrivere su file in modalità diverse
La modalità di apertura determina cosa succede ai dati già presenti. std::ios::app porta ogni scrittura alla fine del file ed è utile per log o registrazioni che devono accumularsi. Se il file non esiste, l’apertura in scrittura può crearlo, purché il percorso e i permessi lo consentano. L’esempio autonomo seguente scrive una riga in modalità append e non richiede che example.txt esista già.
#include <fstream>
#include <iostream>
int main() {
std::ofstream file("example.txt", std::ios::app);
if (!file) {
std::cerr << "Could not open example.txt\n";
return 1;
}
file << "A new log entry\n";
file.close();
if (!file) {
std::cerr << "Could not finish writing example.txt\n";
return 1;
}
return 0;
}
Il caso di runtime fornito è stato completato correttamente e non ha prodotto output nella console. Il codice scrive A new log entry seguito da una nuova riga; se il file contiene già dei dati, la nuova riga viene aggiunta dopo di essi.
Scrivere e sovrascrivere file con ios::trunc
std::ios::trunc elimina il contenuto precedente del file quando lo si apre. Aprire uno std::ofstream in scrittura senza std::ios::app ha normalmente lo stesso effetto di troncamento: specifica std::ios::trunc quando vuoi rendere esplicita questa scelta. Non usare nessuna delle due modalità se devi conservare i dati esistenti.
#include <fstream>
#include <iostream>
int main() {
std::ofstream file("example.txt", std::ios::trunc);
if (!file) {
std::cerr << "Could not open example.txt\n";
return 1;
}
file << "Current report\n";
file.close();
if (!file) {
std::cerr << "Could not finish writing example.txt\n";
return 1;
}
return 0;
}
Il caso di runtime fornito è stato completato correttamente e non ha prodotto output nella console. Il codice scrive in example.txt soltanto Current report e una nuova riga, sostituendo il contenuto precedente.
Scrivere su un file con fstream::write
Usa la funzione membro write dello stream quando i dati sono già in un buffer di caratteri e ne conosci la lunghezza. La funzione accetta un puntatore a caratteri e il numero di caratteri da scrivere; non aggiunge automaticamente un terminatore né una nuova riga. Il conteggio è espresso come dimensione dello stream: passando data.size() vengono scritti i caratteri contenuti nella stringa, senza includere un eventuale carattere null finale. Dopo la chiamata, controlla lo stato dello stream per rilevare errori di scrittura. Consulta la documentazione di cppreference per basic_ostream::write per i dettagli dell’interfaccia.
#include <fstream>
#include <iostream>
#include <string>
int main() {
const std::string data = "C++ buffer data\n";
std::fstream file("buffer.txt", std::ios::out | std::ios::trunc);
if (!file) {
std::cerr << "Could not open buffer.txt\n";
return 1;
}
file.write(data.data(), static_cast<std::streamsize>(data.size()));
if (!file) {
std::cerr << "Could not write buffer.txt\n";
return 1;
}
file.close();
if (!file) {
std::cerr << "Could not finish writing buffer.txt\n";
return 1;
}
return 0;
}
Il caso di runtime fornito è stato completato correttamente e non ha prodotto output nella console. Scrive i caratteri contenuti in data in buffer.txt; la nuova riga fa parte della stringa, mentre non viene scritto alcun carattere null finale.
La scrittura di caratteri e la scrittura di byte si distinguono per il fatto che i dati vengano o meno formattati. L’operatore di inserimento converte i valori in testo, mentre write e fwrite copiano i byte del buffer senza formattarli. Copiare i byte non garantisce da solo che arrivino al file invariati: uno stream aperto in modalità testo può comunque tradurre i caratteri di nuova riga sulle piattaforme che usano un terminatore di riga diverso, come Windows, che converte \n in \r\n in output. Quando contano i byte esatti, apri lo stream in modalità binaria, ad esempio con std::ios::out | std::ios::binary | std::ios::trunc, oppure passa "wb" invece di "w" a fopen, in modo che non avvenga alcuna traduzione.
Scrivere su un file con la funzione C fwrite
Per l’I/O su file nello stile C, fwrite accetta un puntatore, la dimensione di un elemento, il numero di elementi e un FILE*. Il valore restituito indica quanti elementi sono stati scritti; equivale al numero di byte soltanto quando ogni elemento ha dimensione uno. Controlla il conteggio, poi chiudi il file e verifica anche il risultato di fclose, perché gli errori di scrittura nei buffer possono emergere durante la chiusura.
#include <cstdio>
#include <cstring>
#include <iostream>
int main() {
const char data[] = "C file output\n";
const std::size_t size = std::strlen(data);
std::FILE* file = std::fopen("c-output.txt", "w");
if (file == nullptr) {
std::cerr << "Could not open c-output.txt\n";
return 1;
}
const std::size_t written = std::fwrite(data, 1, size, file);
const int close_status = std::fclose(file);
if (written != size || close_status != 0) {
std::cerr << "Could not finish writing c-output.txt\n";
return 1;
}
return 0;
}
Il caso di runtime fornito è stato completato correttamente e non ha prodotto output nella console. Il codice scrive in c-output.txt i caratteri di data, compresa la nuova riga; la modalità "w" crea il file oppure ne tronca il contenuto precedente.
Conclusione
Per il testo normale, usa std::ofstream e <<. Scegli std::ios::app per conservare il contenuto esistente e aggiungere dati in fondo, oppure std::ios::trunc per sostituirlo. Usa write per un buffer di lunghezza nota e fwrite se lavori con l’I/O nello stile C. Controlla lo stato dopo l’apertura e la scrittura; se il programma deve sapere che i dati sono stati scritti completamente, verifica anche gli errori in chiusura.
Domande frequenti
-
Come posso sapere se un file è stato aperto? Controlla direttamente lo stream (
if (!file)) oppure chiamais_open()subito dopo l’apertura. Gestisci l’errore prima di scrivere. -
Come posso aggiungere dati senza sostituire il contenuto esistente? Apri uno stream di output con
std::ios::app. Ogni scrittura viene indirizzata alla fine del file. -
C++ crea un file che non esiste? Gli stream di output e
fopencon modalità"w"possono creare il file se la directory genitore esiste e il processo dispone dei permessi necessari. Se la directory genitore manca o i permessi sono insufficienti, l’apertura non riesce. -
Come posso scrivere più righe? Inserisci caratteri di nuova riga con
<<oppure includili nel buffer passato awrite. Néwritenéfwriteaggiungono automaticamente terminatori di riga. -
Devo chiudere il file? Uno stream di file viene chiuso quando viene distrutto, ma chiamare esplicitamente
close()può rendere chiaro il punto in cui l’operazione è terminata. Se è importante sapere che la scrittura è completa, controlla lo stato dello stream dopo la chiusura. Per unFILE*C, chiamafclosee controllane il valore restituito.