C++ Lettura da un file


Esempio

Esistono diversi modi per leggere i dati da un file.

Se si conosce come vengono formattati i dati, è possibile utilizzare l'operatore di estrazione del flusso ( >> ). Supponiamo che tu abbia un file chiamato foo.txt che contiene i seguenti dati:

John Doe 25 4 6 1987
Jane Doe 15 5 24 1976

Quindi è possibile utilizzare il seguente codice per leggere i dati dal file:

// Define variables.
std::ifstream is("foo.txt");
std::string firstname, lastname;
int age, bmonth, bday, byear;

// Extract firstname, lastname, age, bday month, bday day, and bday year in that order.
// Note: '>>' returns false if it reached EOF (end of file) or if the input data doesn't
// correspond to the type of the input variable (for example, the string "foo" can't be
// extracted into an 'int' variable).
while (is >> firstname >> lastname >> age >> bmonth >> bday >> byear)
    // Process the data that has been read.

L'operatore di estrazione del flusso >> estrae ogni carattere e si arresta se trova un carattere che non può essere memorizzato o se è un carattere speciale:

  • Per i tipi di stringa, l'operatore si ferma in uno spazio bianco ( ) o su una nuova riga ( \n ).
  • Per i numeri, l'operatore si ferma con un carattere non numerico.

Ciò significa che anche la seguente versione del file foo.txt verrà letta con successo dal codice precedente:

John 
Doe 25
4 6 1987


Jane
Doe 
15 5
24
1976

L'operatore di estrazione del flusso >> restituisce sempre lo stream a esso assegnato. Pertanto, più operatori possono essere concatenati insieme per leggere i dati consecutivamente. Tuttavia, uno stream può anche essere usato come espressione booleana (come mostrato nel ciclo while nel codice precedente). Questo perché le classi di flusso hanno un operatore di conversione per il tipo bool . Questo operatore bool() restituirà true fintanto che lo stream non ha errori. Se un flusso entra in uno stato di errore (ad esempio, poiché non è possibile estrarre altri dati), l'operatore bool() restituirà false . Pertanto, il ciclo while nel codice precedente verrà chiuso dopo che il file di input è stato letto fino alla fine.

Se desideri leggere un intero file come una stringa, puoi usare il seguente codice:

// Opens 'foo.txt'.
std::ifstream is("foo.txt");
std::string whole_file;

// Sets position to the end of the file.
is.seekg(0, std::ios::end);

// Reserves memory for the file.
whole_file.reserve(is.tellg());

// Sets position to the start of the file.
is.seekg(0, std::ios::beg);

// Sets contents of 'whole_file' to all characters in the file.
whole_file.assign(std::istreambuf_iterator<char>(is),
  std::istreambuf_iterator<char>());

Questo codice riserva spazio per la string al fine di ridurre le allocazioni di memoria non necessarie.

Se si desidera leggere un file riga per riga, è possibile utilizzare la funzione getline() :

std::ifstream is("foo.txt");   

// The function getline returns false if there are no more lines.
for (std::string str; std::getline(is, str);) {
    // Process the line that has been read.
}

Se vuoi leggere un numero fisso di caratteri, puoi usare la funzione membro del flusso read() :

std::ifstream is("foo.txt");
char str[4];

// Read 4 characters from the file.
is.read(str, 4);

Dopo aver eseguito un comando di lettura, è necessario verificare sempre se è stato impostato il flag di stato di errore failbit , in quanto indica se l'operazione ha avuto esito negativo o meno. Questo può essere fatto chiamando la funzione membro fail() del file stream fail() :

is.read(str, 4); // This operation might fail for any reason.

if (is.fail())
    // Failed to read!