2008-09-25 17 views

Respuesta

17

Podemos hacerlo, pero es una línea de tiempo:

#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; 
} 

Editado: utilizar "istreambuf_iterator" en lugar de "istream_iterator"

+0

Acaba de utilizar el operador ',', esencialmente es como poner un montón de declaraciones con un punto y coma entre ellas en una línea. Pero incluso con eso, supera al mío por debajo de una línea, lindo. –

+0

Si usa un istreambuf_iterator (vea el comentario de Martin York en mi publicación) puede olvidarse de los noskipws. –

+0

Otro comentario, ifstream es temporal, ¿puedes asegurarte de que no se cerrará mientras todavía tenemos istream_iterators? Sería la evaluación de esto ser específica del compilador. –

3

La norma biblioteca de C++ no proporciona una función para hacer esto.

+0

La mejor respuesta. Claro, PUEDE hacerse, pero es un desastre. Es mucho mejor aceptar que no está allí y escribir el tuyo. Una llamada de función única definitivamente será un trazador de líneas. –

2

mejor que puedo hacer es 5 líneas:

#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()); 
+0

¿El truco f.seekg() siempre es correcto sobre la longitud del archivo? ¿Qué hay de la conversión CRLF en Windows? –

+0

Supongo que podría abrir el archivo en modo binario para que no sea un problema. –

10

Su casi posible con una istream_iterator

#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)); 
} 

Editado - se deshizo de flujo de cadena intermedia, ahora copias directamente a (3 líneas!) la cadena, y ahora usando istreambuf_iterator, que ignora el espacio en blanco (gracias Martin York por su comentario).

+0

Ponlo en su propia función y ahora tienes un trazador de líneas. Solo llame a esa función. – Zooba

+0

¿Por qué no utilizar istreambuf_iterator (). No omite el espacio en blanco. –

+0

@Martin York - gracias, en realidad estaba tratando de buscar eso, pero no podía pensar en eso. –

2

¿Qué tal:

#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; 
} 
0

Si lo hace como lo siguiente (pero adecuadamente envuelto bien al contrario más adelante), se puede leer en el archivo sin tener que preocuparse por un byte 0x1A en el archivo (por ejemplo) cortando la lectura del archivo corto. Los métodos sugeridos anteriormente se ahogarán con un 0x1A (por ejemplo) en un archivo.


#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); 
} 

Pero, sí, no es un 1-line ya implementado.

Editar: 0x1A no fue un buen ejemplo ya que ios_base :: binary cubrirá eso. Sin embargo, incluso las transmisiones en C++ a menudo me dan problemas al leer en archivos PNG todo de una vez con .read(). Usar la forma C funciona mejor. Simplemente no puedo recordar un buen ejemplo para mostrar por qué. Probablemente con .read() ing un archivo binario en bloques en un bucle en su lugar puede ser un problema con las transmisiones en C++. Por lo tanto, ignora esta publicación.

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

No es una línea corta o una sola declaración, pero es una línea y realmente no es tan malo.

Cuestiones relacionadas