Question

J'ai besoin d'un moyen simple et rapide pour obtenir une chaîne à partir d'un fichier en C ++ standard. Je peux écrire le mien, mais je veux juste savoir s’il existe déjà une méthode standard en C ++.

Équivalent de ceci si vous connaissez le cacao:

NSString *string = [NSString stringWithContentsOfFile:file];
Était-ce utile?

La solution

Nous pouvons le faire, mais c'est une longue ligne:

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

Modifié: utilisez "" istreambuf_iterator". au lieu de "istream_iterator"

Autres conseils

C'est presque possible avec un istream_iterator (3 lignes!)

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

Modifié - s'est débarrassé du flux de chaîne intermédiaire, copie maintenant directement dans la chaîne, et utilise maintenant istreambuf_iterator, qui ignore les espaces (merci Martin York pour votre commentaire).

La bibliothèque C ++ standard ne fournit pas de fonction pour cela.

Le mieux que je puisse faire est de 5 lignes:

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

Que diriez-vous de:

#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 vous le faites comme suit (mais correctement encapsulé contrairement à ci-dessous), vous pouvez lire le fichier sans vous soucier d’un octet 0x1A dans le fichier (par exemple), ce qui coupe la lecture du fichier. Les méthodes précédemment suggérées s'étoufferont sur un 0x1A (par exemple) dans un fichier.


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

Mais, ce n'est pas un 1-liner déjà implémenté.

Edit: 0x1A n'était pas un bon exemple car ios_base :: binary couvrira cela. Cependant, même dans ce cas, les flux C ++ me posent souvent des problèmes lors de la lecture simultanée de fichiers png avec .read (). L'utilisation de la méthode C fonctionne mieux. Je ne me souviens tout simplement pas d'un bon exemple pour montrer pourquoi. C’est probablement avec .read () qu’un fichier binaire en blocs dans une boucle peut poser problème avec les flux C ++. Donc, ne tenez pas compte de ce message.

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

Ce n'est pas une ligne courte ou à déclaration unique, mais une ligne et ce n'est vraiment pas si mal.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top