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

Question sur stringstream & co

2 réponses
Avatar
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

2 réponses

Avatar
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.

Avatar
David Côme
On Sat, 08 Mar 2008 23:41:41 +0100, Michel Decima
wrote:

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.