Se si desidera utilizzare il metodo formattato, dovete sapere in anticipo quali dati si aspettano e leggerlo in variabili del tipo di dati secondo. Ad esempio, se si sa che il numero è sempre il quinto motivo, come nel tuo esempio, si potrebbe fare questo:
std::string s1, s2, s3, s4;
int n;
std::ifstream in("outdummy.txt");
if (in >> s1 >> s2 >> s3 >> s4 >> n)
{
std::cout << "We read the number " << n << std::endl;
}
D'altra parte, se si sa che il numero è sempre in terza linea, di per sé:
std::string line;
std::getline(in, line); // have line 1
std::getline(in, line); // have line 2
std::getline(in, line); // have line 3
std::istringstream iss(line);
if (iss >> n)
{
std::cout << "We read the number " << n << std::endl;
}
come si può vedere, a leggere un token come una stringa, è sufficiente streaming in una std::string
. È importante ricordare che l'operatore di input formattato lavora token per token, e i token sono separati da spazi bianchi (spazi, tabulazioni, newline). La solita scelta fondamentale da fare è se si elabora un file interamente in token (prima versione) o riga per riga (seconda versione). Per l'elaborazione riga per riga, utilizzare prima getline
per leggere una riga in una stringa e quindi utilizzare un flusso di stringa per tokenizzare la stringa.
Una parola sulla convalida: non è possibile sapere se l'estrazione di un formattata sarà effettivamente successo, perché questo dipende dai dati di input. Pertanto, è necessario sempre controllare se un'operazione di input è riuscita e abortire l'analisi in caso contrario, perché in caso di errore le variabili non conterranno i dati corretti, ma non si avrà modo di saperlo successivamente. Quindi, sempre dire così:
if (in >> v) { /* ... */ } // v is some suitable variable
else { /* could not read into v */ }
if (std::getline(in, line)) { /* process line */ }
else { /* error, no line! */ }
Quest'ultima costruzione di solito è usato in un ciclo while
, a leggere un intero file riga per riga:
while (std::getline(in, line)) { /* process line */ }
Il tuo esempio è sbagliato; non si legge nemmeno "l'intero correttamente". In effetti, quella riga fallisce e 'a' è invariato, ma per qualche motivo l'hai già inizializzato al valore atteso, quindi ti sei bendato. –
@Kerrek ha ragione. Ed è [fornito] (http://stackoverflow.com/questions/7443787/using-c-ifstream-extraction-operator-to-read-formatted-data-from-a-file/7443877#7443877) il corretto e facile -to-use solution - il 'getline' con' string'. –
Perché 'char []'? Perché non 'std :: string'? –