274 votes

Comment lire un fichier entier dans une chaîne std::string en C++ ?

Comment lire un fichier dans un std::string c'est-à-dire lire tout le fichier en une seule fois ?

Le mode texte ou binaire doit être spécifié par l'appelant. La solution doit être conforme aux normes, portable et efficace. Elle ne doit pas copier inutilement les données de la chaîne et doit éviter les réaffectations de mémoire lors de la lecture de la chaîne.

Une façon d'y parvenir serait de statuer sur la taille des fichiers, de redimensionner les std::string y fread() dans le std::string 's const_cast<char*>() 'ed data() . Cela nécessite le std::string Les données de l'utilisateur sont contiguës, ce qui n'est pas requis par la norme, mais semble être le cas pour toutes les implémentations connues. Pire encore, si le fichier est lu en mode texte, la fonction std::string La taille du fichier peut ne pas être égale à la taille du fichier.

Une solution tout à fait correcte, conforme aux normes et portable pourrait être construite en utilisant std::ifstream 's rdbuf() en un std::ostringstream et de là, dans un std::string . Cependant, cela pourrait copier les données de la chaîne et/ou réallouer inutilement de la mémoire.

  • Toutes les implémentations pertinentes de la bibliothèque standard sont-elles suffisamment intelligentes pour éviter toute surcharge inutile ?
  • Y a-t-il un autre moyen de le faire ?
  • Ai-je manqué une fonction cachée de Boost qui fournit déjà la fonctionnalité souhaitée ?

    void slurp(std::string& data, bool is_binary)

-1voto

Thorsten79 Points 7975

N'écrivez jamais dans le tampon const char * de std::string. Jamais, jamais ! C'est une erreur monumentale.

Réservez() de l'espace pour la chaîne entière dans votre std::string, lisez des morceaux de votre fichier de taille raisonnable dans un tampon, et ajoutez() le tout. La taille des morceaux dépend de la taille de votre fichier d'entrée. Je suis presque sûr que tous les autres mécanismes portables et conformes à la STL feront la même chose (tout en étant plus beaux).

-1voto

Mashaim Tahir Points 11
#include <iostream>
#include <fstream>
#include <string.h>
using namespace std;
main(){
    fstream file;
    //Open a file
    file.open("test.txt");
    string copy,temp;
    //While loop to store whole document in copy string
    //Temp reads a complete line
    //Loop stops until temp reads the last line of document
    while(getline(file,temp)){
        //add new line text in copy
        copy+=temp;
        //adds a new line
        copy+="\n";
    }
    //Display whole document
    cout<<copy;
    //close the document
    file.close();
}

-2voto

Barrett Points 1

Je sais que je suis en retard sur la fête, mais maintenant (2021) sur ma machine, c'est l'implémentation la plus rapide que j'ai testée :

#include <fstream>
#include <string>

bool fileRead( std::string &contents, const std::string &path ) {
    contents.clear();
    if( path.empty()) {
        return false;
    }
    std::ifstream stream( path );
    if( !stream ) {
        return false;
    }
    stream >> contents;
    return true;
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X