Lire tout le fichier ASCII dans C ++ std :: ssortingng

J’ai besoin de lire un fichier entier en mémoire et de le placer dans une std::ssortingng ++ std::ssortingng .

Si je devais le lire dans un char[] , la réponse serait très simple:

 std::ifstream t; int length; t.open("file.txt"); // open input file t.seekg(0, std::ios::end); // go to the end length = t.tellg(); // report location (this is the length) t.seekg(0, std::ios::beg); // go back to the beginning buffer = new char[length]; // allocate memory for a buffer of appropriate dimension t.read(buffer, length); // read the whole file into the buffer t.close(); // close file handle // ... Do stuff with buffer here ... 

Maintenant, je veux faire exactement la même chose, mais en utilisant un std::ssortingng au lieu d’un char[] . Je veux éviter les boucles, c’est-à-dire que je ne veux pas:

 std::ifstream t; t.open("file.txt"); std::ssortingng buffer; std::ssortingng line; while(t){ std::getline(t, line); // ... Append line to buffer and go on } t.close() 

Des idées?

Mise à jour: Il s’avère que cette méthode, tout en suivant bien les expressions STL, est en réalité étonnamment inefficace! Ne faites pas cela avec de gros fichiers. (Voir: http://insanecoding.blogspot.com/2011/11/how-to-read-in-file-in-c.html )

Vous pouvez faire un streambuf iterator du fichier et initialiser la chaîne avec:

 #include  #include  #include  std::ifstream t("file.txt"); std::ssortingng str((std::istreambuf_iterator(t)), std::istreambuf_iterator()); 

Vous ne savez pas d’où t.open("file.txt", "r") la t.open("file.txt", "r") . Pour autant que je sache, ce n’est pas une méthode que std::ifstream a. On dirait que vous l’avez confondu avec le fopen de C.

Edit: notez également les parenthèses supplémentaires autour du premier argument du constructeur de chaîne. Celles-ci sont essentielles . Ils évitent le problème connu sous le nom de ” parade la plus agressive “, qui dans ce cas ne vous donnera pas une erreur de compilation comme elle le fait habituellement, mais vous donnera des résultats intéressants (lire: faux).

Suivant le sharepoint KeithB dans les commentaires, voici un moyen de le faire qui alloue toute la mémoire en amont (plutôt que de compter sur la réallocation automatique de la classe de chaînes):

 #include  #include  #include  std::ifstream t("file.txt"); std::ssortingng str; t.seekg(0, std::ios::end); str.reserve(t.tellg()); t.seekg(0, std::ios::beg); str.assign((std::istreambuf_iterator(t)), std::istreambuf_iterator()); 

Il y a plusieurs possibilités. Un j’aime utiliser un ssortingngstream comme intermédiaire:

 std::ifstream t("file.txt"); std::ssortingngstream buffer; buffer << t.rdbuf(); 

Maintenant, le contenu de "fichier.txt" est disponible dans une chaîne comme buffer.str() .

Une autre possibilité (bien que je ne l'aime certainement pas aussi) ressemble beaucoup à votre original:

 std::ifstream t("file.txt"); t.seekg(0, std::ios::end); size_t size = t.tellg(); std::ssortingng buffer(size, ' '); t.seekg(0); t.read(&buffer[0], size); 

Officiellement, cela n'est pas nécessaire pour fonctionner sous la norme C ++ 98 ou 03 (la chaîne n'est pas requirejse pour stocker les données de manière contiguë), mais en fait, elle fonctionne avec toutes les implémentations connues et C ++ 11 requirejs un stockage contigu , donc il est garanti de travailler avec eux.

Pour ce qui est de savoir pourquoi je n’aime pas ce dernier aussi: d’abord parce que c’est plus long et plus difficile à lire. Deuxièmement, parce que vous devez initialiser le contenu de la chaîne avec des données qui ne vous intéressent pas, écrivez immédiatement ces données (oui, le temps d’initialisation est généralement insignifiant par rapport à la lecture, donc cela n’a probablement pas d’importance , mais pour moi, c'est quand même un peu faux. Troisièmement, dans un fichier texte, la position X dans le fichier ne signifie pas nécessairement que vous aurez lu les caractères X pour atteindre ce point - il n'est pas nécessaire de prendre en compte des éléments tels que les traductions de fin de ligne. Sur les systèmes réels qui font de telles traductions (par exemple, Windows), le formulaire traduit est plus court que celui du fichier (par exemple, "\ r \ n" dans le fichier devient "\ n" dans la chaîne traduite). est réservé un petit espace supplémentaire que vous n'utilisez jamais. Encore une fois, cela ne pose pas vraiment de problème majeur mais se sent un peu mal quand même.

Je pense que le meilleur moyen est d’utiliser un stream de chaînes. simple et rapide !!!

 ifstream inFile; inFile.open(inFileName);//open the input file ssortingngstream strStream; strStream << inFile.rdbuf();//read the file string str = strStream.str();//str holds the content of the file cout << str << endl;//you can do anything with the string!!! 

Vous ne pouvez pas trouver cela dans un livre ou un site, mais j’ai découvert que cela fonctionne plutôt bien:

 ifstream ifs ("filename.txt"); ssortingng s; getline (ifs, s, (char) ifs.eof()); 

Essayez l’une de ces deux méthodes:

 ssortingng get_file_ssortingng(){ std::ifstream ifs("path_to_file"); return ssortingng((std::istreambuf_iterator(ifs)), (std::istreambuf_iterator())); } ssortingng get_file_ssortingng2(){ ifstream inFile; inFile.open("path_to_file");//open the input file ssortingngstream strStream; strStream << inFile.rdbuf();//read the file return strStream.str();//str holds the content of the file } 

J’ai trouvé un autre moyen qui fonctionne avec la plupart des istreams, y compris std :: cin!

 std::ssortingng readFile() { ssortingngstream str; ifstream stream("Hello_World.txt"); if(stream.is_open()) { while(stream.peek() != EOF) { str << (char) stream.get(); } stream.close(); return str.str(); } } 

Je pourrais le faire comme ça:

 void readfile(const std::ssortingng &filepath,std::ssortingng &buffer){ std::ifstream fin(filepath.c_str()); getline(fin, buffer, char(-1)); fin.close(); } 

Si c’est quelque chose à désapprouver, s’il vous plaît laissez-moi savoir pourquoi

Si vous utilisez glibmm, vous pouvez essayer Glib :: file_get_contents .

 #include  #include  int main() { auto filename = "my-file.txt"; try { std::ssortingng contents = Glib::file_get_contents(filename); std::cout << "File data:\n" << contents << std::endl; catch (const Glib::FileError& e) { std::cout << "Oops, an error occurred:\n" << e.what() << std::endl; } return 0; } 

Je ne pense pas que vous puissiez le faire sans une boucle explicite ou implicite, sans lire dans un tableau de caractères (ou un autre conteneur) en premier et dix en construisant la chaîne. Si vous n’avez pas besoin des autres fonctionnalités d’une chaîne, vous pouvez utiliser le vector la même manière que vous utilisez actuellement un caractère char * .