Domanda

Ho bisogno di un modo semplice e veloce per ottenere una stringa da un file in C ++ standard. Posso scrivere il mio, ma voglio solo sapere se esiste già un modo standard, in C ++.

Equivalente di questo se conosci il cacao:

NSString *string = [NSString stringWithContentsOfFile:file];
È stato utile?

Soluzione

Possiamo farcela, ma è una lunga fila:

#include<fstream>
#include<iostream>
#include<iterator>
#include<string>

using namespace std;

int main()
{
    // The one-liner
    string fileContents(istreambuf_iterator<char>(ifstream("filename.txt")), istreambuf_iterator<char>());

    // Check result
    cout << fileContents;
}

Modificato: usa " istreambuf_iterator " invece di " istream_iterator "

Altri suggerimenti

È quasi possibile con un istream_iterator (3 righe!)

#include <iostream>
#include <fstream>
#include <iterator>
#include <string>
#include <sstream>

using namespace std;

int main()
{
    ifstream file("filename.txt");
    string fileContents;

    copy(istreambuf_iterator<char>(file),
              istreambuf_iterator<char>(),
              back_inserter(fileContents));
}

Modificato: elimina il flusso di stringa intermedio, ora copia direttamente nella stringa e ora utilizza istreambuf_iterator, che ignora gli spazi bianchi (grazie Martin York per il tuo commento).

La libreria C ++ standard non fornisce una funzione per farlo.

Il meglio che posso fare è 5 righe:

#include <fstream>
#include <vector>
using namespace std;

ifstream f("filename.txt");
f.seekg(0, ios::end);
vector<char> buffer(f.tellg());
f.seekg(0, ios::beg);
f.read(&buffer[0], buffer.size());

Che ne dici di:

#include <fstream>
#include <sstream>
#include <iostream>

using namespace std;

int main( void )
{
  stringstream os(stringstream::out);
  os << ifstream("filename.txt").rdbuf();
  string s(os.str());
  cout << s << endl;
}

Se lo fai nel modo seguente (ma correttamente racchiuso bene a differenza di seguito), puoi leggere il file senza preoccuparti di un byte 0x1A nel file (ad esempio) abbreviando la lettura del file. I metodi precedentemente suggeriti si strozzeranno su uno 0x1A (ad esempio) in un file.


#include <iostream>
#include <cstdio>
#include <vector>
#include <cstdlib>
using namespace std;

int main() {
    FILE* in = fopen("filename.txt", "rb");
    if (in == NULL) {
        return EXIT_FAILURE;
    }
    if (fseek(in, 0, SEEK_END) != 0) {
        fclose(in);
        return EXIT_FAILURE;
    }
    const long filesize = ftell(in);
    if (filesize == -1) {
        fclose(in);
        return EXIT_FAILURE;
    }
    vector<unsigned char> buffer(filesize);
    if (fseek(in, 0, SEEK_SET) != 0 || fread(&buffer[0], sizeof(buffer[0]), buffer.size(), in) != buffer.size() || ferror(in) != 0) {
        fclose(in);
        return EXIT_FAILURE;
    }
    fclose(in);
}

Ma, comunque, non è un 1-liner già implementato.

Modifica: 0x1A non è stato un buon esempio dato che ios_base :: binary lo tratterà. Tuttavia, anche allora i flussi C ++ spesso mi danno problemi quando leggo tutti i file png contemporaneamente con .read (). L'uso del modo C funziona meglio. Non riesco proprio a ricordare un buon esempio per mostrare il perché. Probabilmente era con .read () che ingingeva un file binario in blocchi in un ciclo invece che poteva essere un problema con i flussi C ++. Quindi, ignora questo post.

std::string temp, file; std::ifstream if(filename); while(getline(if, temp)) file += temp;

Non è una riga breve o con una singola istruzione, ma è una riga e non è poi così male.

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