Domanda

Si consideri il seguente programma C ++, che prende un file e stampa ogni riga. Si tratta di una fetta di un programma più ampio in cui ho poi aggiungere al file, in base a quello che vedo.

#include <fstream>
using std::fstream;
#include <iostream>
#include <string>
using std::string;

int main()
{
 fstream file("file.txt", fstream::in | fstream::out | fstream::app);

 string line;
 while (std::getline(file, line))
  std::cerr << line << std::endl;

 return 0;
}

Ora applicare questa versione di file.txt (Una parola sulla prima riga, seguito da un ritorno a capo):

Rain

Sulla mia macchina (Snow Leopard), Questo stampa nulla. A ben vedere, la prima chiamata a getline non riesce. Stranamente, non riesce anche se posso aggiungere una seconda linea: ancora nulla viene stampato

Qualcuno può risolvere questo mistero?

È stato utile?

Soluzione

Quando si dice:

fstream file("file.txt", fstream::in | fstream::out | fstream::app);

si apre il file in modalità append - vale a dire alla fine. Basta aprirlo in modalità di lettura:

fstream file("file.txt", fstream::in );

o utilizzare un ifstream:

ifstream file("file.txt" );

E naturalmente come suggerisce Earwicker, si dovrebbe sempre verificare che l'apertura è riuscita.

Se siete determinati ad aprire in modalità di aggiunta, è possibile spostare il puntatore di lettura esplicitamente:

#include <fstream>
#include <iostream>
#include <string>
using namespace std;

int main() {
    fstream file( "afile.txt", ios::in | ios::out | ios::app );
    if ( ! file.is_open()  ) {
        cerr << "open failed" << endl;
        return 1;
    }
    else {
        file.seekg( 0, ios::beg );   // move read pointer
        string line;
        while( getline( file, line ) ) {
            cout << line << endl;
        }
    }
}

Modifica Sembra che la combinazione di flag utilizzati in apertura del file porta ad un comportamento specifica implementazione. Il codice precedente funziona con g ++ su Windows, ma non con g ++ su Linux.

Altri suggerimenti

Si dovrebbe verificare se il file è in realtà stato aperto:

if (!file)
    std::cerr << "Oh dear" << std::endl;

Aggiornamento: , infatti, il file probabilmente è stato aperto, ma è in modalità di accodamento - vedere la risposta di NEII

.

Aggiornamento 2: va bene, sbagliato di nuovo. In g di Leopard ++, almeno, il file non verrà aperto perché la bandiera app è incompatibile con la bandiera in. Quindi il controllo sopra stamperà Oh dear.

In MSVC ++, si va avanti e si apre il file, a quanto pare con la posizione di lettura alla partenza, il che spiega il motivo per cui altre persone hanno visto il lavoro e mi scuso per aver dubitato loro veridicità!

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top