Leia o conteúdo do arquivo em uma string em C ++

Duplicar Possível:
Qual é a melhor maneira de slurp um arquivo em um std :: string em c + +?

Em linguagens de script como o Perl, é possível ler um arquivo em uma variável de uma só vez.

open(FILEHANDLE,$file); $content=; 

Qual seria a maneira mais eficiente de fazer isso em C ++?

Como isso:

 #include  #include  int main(int argc, char** argv) { std::ifstream ifs("myfile.txt"); std::string content( (std::istreambuf_iterator(ifs) ), (std::istreambuf_iterator() ) ); return 0; } 

A declaração

  std::string content( (std::istreambuf_iterator(ifs) ), (std::istreambuf_iterator() ) ); 

pode ser dividido em

 std::string content; content.assign( (std::istreambuf_iterator(ifs) ), (std::istreambuf_iterator() ) ); 

que é útil se você quiser apenas sobrescrever o valor de uma variável std :: string existente.

O mais eficiente, mas não o caminho C ++, seria:

  FILE* f = fopen(filename, "r"); // Determine file size fseek(f, 0, SEEK_END); size_t size = ftell(f); char* where = new char[size]; rewind(f); fread(where, sizeof(char), size, f); delete[] where; 

# EDIT – 2

Apenas testei a variante std::filebuf também. Parece que ele pode ser chamado de a melhor abordagem de C ++, mesmo que não seja uma abordagem bastante C ++, mas mais um wrapper. De qualquer forma, aqui está o pedaço de código que funciona quase tão rápido quanto o C simples.

  std::ifstream file(filename, std::ios::binary); std::streambuf* raw_buffer = file.rdbuf(); char* block = new char[size]; raw_buffer->sgetn(block, size); delete[] block; 

Eu fiz um benchmark rápido aqui e os resultados estão seguindo. O teste foi feito na leitura de um arquivo binário de 65536K com os modos apropriados ( std::ios:binary e rb ).

 [==========] Running 3 tests from 1 test case. [----------] Global test environment set-up. [----------] 4 tests from IO [ RUN ] IO.C_Kotti [ OK ] IO.C_Kotti (78 ms) [ RUN ] IO.CPP_Nikko [ OK ] IO.CPP_Nikko (106 ms) [ RUN ] IO.CPP_Beckmann [ OK ] IO.CPP_Beckmann (1891 ms) [ RUN ] IO.CPP_Neil [ OK ] IO.CPP_Neil (234 ms) [----------] 4 tests from IO (2309 ms total) [----------] Global test environment tear-down [==========] 4 tests from 1 test case ran. (2309 ms total) [ PASSED ] 4 tests. 

O mais eficiente é criar um buffer do tamanho correto e depois ler o arquivo no buffer.

 #include  #include  int main() { std::ifstream file("Plop"); if (file) { /* * Get the size of the file */ file.seekg(0,std::ios::end); std::streampos length = file.tellg(); file.seekg(0,std::ios::beg); /* * Use a vector as the buffer. * It is exception safe and will be tidied up correctly. * This constructor creates a buffer of the correct length. * Because char is a POD data type it is not initialized. * * Then read the whole file into the buffer. */ std::vector buffer(length); file.read(&buffer[0],length); } } 

Não deve haver \0 em arquivos de texto.

 #include #include using namespace std; int main(){ fstream f(FILENAME, fstream::in ); string s; getline( f, s, '\0'); cout << s << endl; f.close(); } 

Isso depende de muitas coisas, como qual é o tamanho do arquivo, qual é o seu tipo (texto / binário) etc. Algum tempo atrás eu testei a seguinte function em versões usando iteradores streambuf – era duas vezes mais rápido:

 unsigned int FileRead( std::istream & is, std::vector  & buff ) { is.read( &buff[0], buff.size() ); return is.gcount(); } void FileRead( std::ifstream & ifs, string & s ) { const unsigned int BUFSIZE = 64 * 1024; // reasoable sized buffer std::vector  buffer( BUFSIZE ); while( unsigned int n = FileRead( ifs, buffer ) ) { s.append( &buffer[0], n ); } } 

talvez não seja o mais eficiente, mas lê dados em uma linha:

 #include #include #include main(int argc,char *argv[]){ // read standard input into vector: std::vectorv(std::istream_iterator(std::cin), std::istream_iterator()); std::cout << "read " << v.size() << "chars\n"; } 

Aqui está um método baseado em iterador.

 ifstream file("file", ios::binary); string fileStr; istreambuf_iterator inputIt(file), emptyInputIt back_insert_iterator stringInsert(fileStr); copy(inputIt, emptyInputIt, stringInsert);