Pregunta

Necesito una forma rápida y fácil de obtener una cadena de un archivo en C ++ estándar. Puedo escribir el mío, pero solo quiero saber si ya existe una forma estándar, en C ++.

Equivalente a esto si sabes Cocoa:

NSString *string = [NSString stringWithContentsOfFile:file];
¿Fue útil?

Solución

Podemos hacerlo pero es una larga cola:

#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: use " istreambuf_iterator " en lugar de " istream_iterator "

Otros consejos

Es casi posible con un istream_iterator (¡3 líneas!)

#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: eliminó el flujo de cadena intermedio, ahora se copia directamente en la cadena y ahora usa istreambuf_iterator, que ignora los espacios en blanco (gracias a Martin York por tu comentario).

La biblioteca estándar de C ++ no proporciona una función para hacer esto.

Lo 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());

Cómo sobre: ??

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

Si lo hace de la siguiente manera (pero se ajusta adecuadamente, a diferencia de lo que se muestra a continuación), puede leer el archivo sin preocuparse por un byte de 0x1A en el archivo (por ejemplo) que acorta la lectura del archivo. 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-liner ya implementado.

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

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

No es una línea corta o de una sola frase, pero es una línea y realmente no es tan mala.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top