Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

std::string et ifstream

4 réponses
Avatar
Marc G
Une question bête :
comment mettre le plus rapidement possible le contenu d'un fichier texte
(char simples) dans une string ?
std::string x;
ifstream f("toto.txt");
et maintenant, je fais quoi ? :-))
Il faut créer un tampon, lire char par char (while(!f.eof()) ... ) ? Quel
est le moyen de transfert le plus rapide ?
merci à vous

4 réponses

Avatar
Marc G
je m'excuse d'avoir posté trop tôt...
j'ai trouvé ceci :

std::ifstream infile("toto.txt",std::ios::in);
std::string x;
std::getline(infile,x,'');

c'est la meilleure solution ?
merci à vous
Marc
Avatar
James Kanze
On May 11, 10:40 pm, "Marc G" wrote:
Une question bête :
comment mettre le plus rapidement possible le contenu d'un fichier texte
(char simples) dans une string ?
std::string x;
ifstream f("toto.txt");
et maintenant, je fais quoi ? :-))
Il faut créer un tampon, lire char par char (while(!f.eof()) ... ) ?


Ça, c'est sûrement faux. std::istream::eof() ne sert jamais
comme contrôle d'une boucle.

Quel est le moyen de transfert le plus rapide ?


Le moyen le plus rapide va dépendre certainement de
l'implémentation. S'il y a vraiment de problème de performance,
mapper le fichier en mémoire, et travailler directement dessus,
et généralement ce qu'il y a de plus rapide. Mais il faut bien
se faire avec des requêtes système et l'API qui lui est propre.
Et aussi avec le fait que la représentation des fins de lignes
est celle du système.

Sinon, la forme classique, c'est :

std::istringstream ss ;
ss << f.rdbuf() ;
std::string s( ss.str() ) ;


Seulement, je doute qu'elle soit la plus rapide ; il y a une
copy en plus, et certaines implémentations de istringstream ne
sont pas des plus rapides non plus.

De nos jours :

std::string s( (std::istream_iterator< char >( f )),
(std::istream_iterator< char >() ) ) ;

(ou la même chose avec istreambuf_iterator) a la côte. Là aussi,
les performances dépendent beaucoup de l'implémentation.

Ce que je suggère, c'est d'en choisir un des deux dernières
suggestions, au hazard, et puis de n'utiliser que des itérateurs
pour y accéder, avec le type d'itérateur défini par un typedef,
et en étant très tolérant en ce qui concerne la représentation
des fins de lignes. Ensuite, si tu constates de vrais problèmes
de performance, toutes les options te sont encore ouvertes, y
compris l'utilisation de la mémoire mappée. (Pour commencer,
c'est fort possible que l'utilisation de std::vector< char >
s'avère plus rapide que std::string.)

Note que ça suppose l'utilisation des algorithmes de
<algorithm>, genre find, find_first_of, etc., plutôt que des
fonctions membre de std::string. (Les noms en sont parfois
déroutant, mais toute la fonctionalité y est.)

--
James Kanze (Gabi Software) email:
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Avatar
Marc G
Mais il faut bien
se faire avec des requêtes système et l'API qui lui est propre.
Et aussi avec le fait que la représentation des fins de lignes
est celle du système.


Je te remercie pour tes suggestions.
Je suis sous windows et je cherche à charger des fichiers texte de
programmes (rarement plus de 1000 lignes) qui sont ensuite interprétés.
Ce que j'ai écrit dans mon deuxième post fonctionne : j'ai trouvé qu'on
pouvait utiliser getline avec un délimiteur autre que 'n'.

std::ifstream infile("toto.txt",std::ios::in);
std::string x;
std::getline(infile,x,''); // '', c'est le caractère utilisé pour les
fin de fichier et getline lit tout jusqu'à ce caractère exclu.

Par rapport aux deux solutions que tu proposes, c'est moins performant ?
Marc

Avatar
James Kanze
On May 12, 6:56 pm, "Marc G" wrote:
Mais il faut bien
se faire avec des requêtes système et l'API qui lui est propre.
Et aussi avec le fait que la représentation des fins de lignes
est celle du système.


Je te remercie pour tes suggestions.
Je suis sous windows et je cherche à charger des fichiers texte de
programmes (rarement plus de 1000 lignes) qui sont ensuite interprét és.
Ce que j'ai écrit dans mon deuxième post fonctionne : j'ai trouvé q u'on
pouvait utiliser getline avec un délimiteur autre que 'n'.

std::ifstream infile("toto.txt",std::ios::in);
std::string x;
std::getline(infile,x,''); // '', c'est le caractère utilisé pou r les
fin de fichier et getline lit tout jusqu'à ce caractère exclu.

Par rapport aux deux solutions que tu proposes, c'est moins performant ?


Qui sait. Probablement, parce qu'il faut que la fonction
d'entrée regarde chaque caractère, mais ce n'est pas dit que la
différence soit importante.

Ce qui me plaît pas avec cette solution, c'est qu'elle transmet
le mauvais message à la person qui le lit. Tu ne veux pas lire
qu'une seule ligne, et tu ne t'attends pas à ce que les lignes
soient séparées par des ''.

--
James Kanze (Gabi Software) email:
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34