Question sur stringstream & co

Le
David Côme
Bonjour à tous.
J'ai une petite question sur les stringstream.
Voici le code :
#include <sstream>
#include <iostream>

using namespace std;

int main()
{
const string st("+0;-1;|-2;-3;|");

stringstream stream(st);
string tmp,tmp2;

istringstream stream1;//(1)
while( std::getline(stream,tmp,'|') )
{

stringstream flx(tmp);

while( std::getline(flx,tmp2,';') )
{

//si je déplace (1) ici ca marche //(2)
istringstream stream1;
stream1.str(tmp2);
int i=0;
stream1 >> i;

cout << i << endl;
}
stream1.str(""); //(3)
}

return 0;
}

Comme mit en commentaire, si je déplace la ligne (1) en (2) et commente
(3), mon code marche; cad que i vaut bien 0,-1,-2,-3.
Par contre si je le laisse tel quel, il compile mais l'extraction rate
toujours et i vaut tout le temps 0.

Quelqu'un sait t'il pourquoi ?

Merci
Questions / Réponses high-tech
Vidéos High-Tech et Jeu Vidéo
Téléchargements
Vos réponses
Gagnez chaque mois un abonnement Premium avec GNT : Inscrivez-vous !
Trier par : date / pertinence
Michel Decima
Le #1342667
Bonjour à tous.
J'ai une petite question sur les stringstream.
Voici le code :
#include <sstream>
#include <iostream>

using namespace std;

int main()
{
const string st("+0;-1;|-2;-3;|");

stringstream stream(st);
string tmp,tmp2;

istringstream stream1;//(1)
while( std::getline(stream,tmp,'|') )
{

stringstream flx(tmp);

while( std::getline(flx,tmp2,';') )
{

//si je déplace (1) ici ca marche //(2)
istringstream stream1;
stream1.str(tmp2);
int i=0;
stream1 >> i;

cout << i << endl;
}
stream1.str(""); //(3)
}

return 0;
}

Comme mit en commentaire, si je déplace la ligne (1) en (2) et commente
(3), mon code marche; cad que i vaut bien 0,-1,-2,-3.
Par contre si je le laisse tel quel, il compile mais l'extraction rate
toujours et i vaut tout le temps 0.


Dans le code "tel quel", l'extraction ne rate pas toujours : la premiere
reussi, et tu obtiens 0 par ce qu'il y a un "0" a extraire au debut de
la chaine. Si tu remplacait la chaine par "+4;-1;|-2;-3;|", tu
obtiendrais 4 0 0 0. Tu pourrais aussi tester la reussite de
l'extraction avec

if ( stream >> i )
cout << i << endl ;
else
cout << "failed" << endl ;

ca peut aider ;)

Quelqu'un sait t'il pourquoi ?


Oui.

Apres la premiere extraction (reussie) sur stream1, celui ci a atteint
la fin du flux, donc le flag eof est positionne (cf la valeur de
rdstate() ou eof()). Donc la prochaine operation de lecture va forcement
echouer puisque l'etat du stream n'est plus good().

A l'iteration suivante, tu modifie le contenu de stream1 avec str(), le
prochain caractere lu sera bien le premier caractere de tmp2, mais tu
n'a pas reinitialisé les flags d'etat, qui sont toujours a eof. La
deuxieme lecture echoue forcement, et l'etat passe alors a eof|failed
(et il y reste pour les iterations ulterieures).

Si tu remplace (3) par stream1.clear() qui reinitialise l'etat du flux,
tu devrais obtenir le resultat attendu.

L'avantage de declarer stream dans la boucle, au plus pres de son
utilisation, c'est qu'on a toujours un objet "propre", parce qu'il vient
d'etre initialise. Si tu le sort de la boucle, alors il faut le
reinitialiser completement, sans rien oublier, pour que ca marche.

David Côme
Le #1393871
On Sat, 08 Mar 2008 23:41:41 +0100, Michel Decima

Bonjour à tous.
J'ai une petite question sur les stringstream.
Voici le code :
#include <sstream>
#include <iostream>
using namespace std;
int main()
{
const string st("+0;-1;|-2;-3;|");
stringstream stream(st);
string tmp,tmp2;
istringstream stream1;//(1)
while( std::getline(stream,tmp,'|') )
{
stringstream flx(tmp);
while( std::getline(flx,tmp2,';') )
{
//si je déplace (1) ici ca marche //(2)
istringstream stream1;
stream1.str(tmp2);
int i=0;
stream1 >> i;
cout << i << endl;
}
stream1.str(""); //(3)
}
return 0;
}
Comme mit en commentaire, si je déplace la ligne (1) en (2) et
commente (3), mon code marche; cad que i vaut bien 0,-1,-2,-3.
Par contre si je le laisse tel quel, il compile mais l'extraction rate
toujours et i vaut tout le temps 0.


Dans le code "tel quel", l'extraction ne rate pas toujours : la premiere
reussi, et tu obtiens 0 par ce qu'il y a un "0" a extraire au debut de
la chaine. Si tu remplacait la chaine par "+4;-1;|-2;-3;|", tu
obtiendrais 4 0 0 0. Tu pourrais aussi tester la reussite de
l'extraction avec

if ( stream >> i )
cout << i << endl ;
else
cout << "failed" << endl ;

ca peut aider ;)

Quelqu'un sait t'il pourquoi ?


Oui.

Apres la premiere extraction (reussie) sur stream1, celui ci a atteint
la fin du flux, donc le flag eof est positionne (cf la valeur de
rdstate() ou eof()). Donc la prochaine operation de lecture va forcement
echouer puisque l'etat du stream n'est plus good().

A l'iteration suivante, tu modifie le contenu de stream1 avec str(), le
prochain caractere lu sera bien le premier caractere de tmp2, mais tu
n'a pas reinitialisé les flags d'etat, qui sont toujours a eof. La
deuxieme lecture echoue forcement, et l'etat passe alors a eof|failed
(et il y reste pour les iterations ulterieures).

Si tu remplace (3) par stream1.clear() qui reinitialise l'etat du flux,
tu devrais obtenir le resultat attendu.

L'avantage de declarer stream dans la boucle, au plus pres de son
utilisation, c'est qu'on a toujours un objet "propre", parce qu'il vient
d'etre initialise. Si tu le sort de la boucle, alors il faut le
reinitialiser completement, sans rien oublier, pour que ca marche.



Ok.

Merci.


Publicité
Poster une réponse
Anonyme