Page principale | Pages associées

Les Itérateurs de Flux

Les itérateurs de flux... enfin ça commence à devenir intéressant. Ils permettent d'utiliser les flux d'entrée(istream_iterator) et les flux de sortie (ostream_iterator) dans les algorithmes de la STL.

On va prendre un exemple simple : afficher la liste des mots uniques lu à partir de l'entrée standard. On va voir, comment grâce à la STL, ce programme est rapidement écrit.

Je vais utiliser une méthode simple peut être pas la plus rapide mais qui a l'avantage de présenter les deux itérateurs simplement.

Remarque : pour cette exemple, j'ai du utiliser deux méthodes car mon compilateur vc++6.0 ne reconnait une des formes de constructeur (il existe un patch pour ça) J'ai donc utilisé un define NOPATCH dans le makefile pour vc98. Les autres compilateurs peuvent utiliser indépendement l'une ou l'autres des méthodes.

#include <iostream> #include <string> #include <set> #include <algorithm> #include <iterator> using namespace std; int main() { #ifdef NOPATCH // Déclaration de l'ensemble de mots set<string> sString; // Remplissage du set copy( istream_iterator<string>(cin), istream_iterator<string>(), inserter( sString, sString.end() ) );
On a déjà vu copy(), tout va bien. istream_iterator<string>(cin) permet de définir le début pour l'algorithme copie. copy va donc utiliser l'opérateur >> disponible sur cin pour lire des strings jusqu'à la fin qui est défini par istream_iterator<string>() soit la fin du flux soit une autre erreur. inserter( sString, sString.end() ) on a déjà vu mais dans le doute... utilise la méthode insert() sur le set<string> pour insérer la chaîne lue du flux dans le set.
#else // Déclaration de l'ensemble de mots set<string> sString( (istream_iterator<string>(cin)), istream_iterator<string>() );
On utilise la forme du constructeur du set prenant deux itérateurs pour le début et la fin des éléments à insérer. istream_iterator<string>(cin) permet de définir le début. Le istream_iterator utilise l'opérateur >> disponible sur cin pour lire des strings jusqu'à la fin qui est défini par istream_iterator<string>() soit la fin du flux soit une autre erreur.
#endif // On copie les mots sans doublons sur la sortie standard copy( sString.begin(), sString.end(), ostream_iterator<string>( cout, "\n" ) );
On utilise copy pour cette deuxième ligne de code. copy va donc écrire tous les éléments de l'ensemble vers le flux de sortie standard. Pour cela, on déclare un ostream_iterator<string>( cout, "\n" ) qui permet d'utiliser l'opérateur >> sur les chaînes du cout en ajoutant la chaîne "\n" après chaque élement écrit.
}

Voilà, le programme est terminé avec 2 lignes de code. On notera que le notion de mot ici est définit au sens du flux Ce sont les espaces et les tabulations qui servent de séparateur. En français on aurait ajouter la ponctuation. Ca peut faire l'objet d'un exercice. Il existe plusieurs manière de faire ce même programme, avec un simple vecteur par exemple... à vous de jouer.

Voici la fin de ce deuxième tutorial. Il nous a présenté le vector, la list, le set, et le map pour les conteneurs. Un rapide coup d'oeil nous a permis de découvrir quelques algorithmes de la STL. Enfin, le dernier point abordé concernait les itérateurs d'insertions et de flux. A partir de maintenant, la STL ne vous est plus trop inconnu. j'espère vous avoir donné envie d'aller jetter un coup d'oeil dans des ouvrages plus complet qui sont pour moi des références incontournables (bien que certains soient en anglais). Les commentaires n'engagent que moi.

En plus de ces ouvrages payant (si vous les trouvez sans payer, c'est pas bien, ils valent vraiment le prix qu'ils coûtent), il existe de nombreux ouvrages sur le net, je pense notamment aux livres de Eckel, Thinking in C++ qui sont très bien pour débuter et plus. Attention, de nombreux tutoriaux sont très mauvais en plus d'être incorrects (j'espère que celui-ci ne contient pas trop d'erreurs en tout cas).

Je ne pense plus faire des tutoriaux maintenant (une description résumée mais complète de la STL semble un peu trop gros à faire et reste souvent indigeste pour le commun des lecteurs). bien qu'il reste beaucoup de chose à dire et de pièges à éviter dans l'utilisation de la STL. J'essayerai plutôt de présenter des solutions à des cas concret d'utilisations du C++. En fait, le plus dur est de trouver de bon exemple, assez court mais surtout pertinant. Il y a aussi les modèles de conception (design patterns) qui sont intéressant à implémenter en C++ dont j'aimerais causer un peu. Qui sait... en attendant programmez bien.

Hylvenir

Si vous détectez des erreurs, ou des commentaires, n'hésitez pas : mail: hylvenir@libertysurf.fr


Le source complet :
#include <iostream> #include <string> #include <set> #include <algorithm> #include <iterator> using namespace std; int main() { #ifdef NOPATCH // Déclaration de l'ensemble de mots set<string> sString; // Remplissage du set copy( istream_iterator<string>(cin), istream_iterator<string>(), inserter( sString, sString.end() ) ); #else // Déclaration de l'ensemble de mots set<string> sString( (istream_iterator<string>(cin)), istream_iterator<string>() ); #endif // On copie les mots sans doublons sur la sortie standard copy( sString.begin(), sString.end(), ostream_iterator<string>( cout, "\n" ) ); }
00001 #include <iostream> 00002 #include <string> 00003 #include <set> 00004 #include <algorithm> 00005 #include <iterator> 00006 using namespace std; 00007 00008 int main() 00009 { 00010 #ifdef NOPATCH 00011 // Déclaration de l'ensemble de mots 00012 set<string> sString; 00013 // Remplissage du set 00014 copy( istream_iterator<string>(cin), istream_iterator<string>(), 00015 inserter( sString, sString.end() ) ); 00016 #else 00017 // Déclaration de l'ensemble de mots 00018 set<string> sString( (istream_iterator<string>(cin)), 00019 istream_iterator<string>() ); 00020 #endif 00021 00022 // On copie les mots sans doublons sur la sortie standard 00023 copy( sString.begin(), sString.end(), 00024 ostream_iterator<string>( cout, "\n" ) ); 00025 }

Dernière modification : Sun Jul 4 20:19:13 2004