|
|
|
#1 |
|
Messages: n/a
Hébergeur: |
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 |
|
Messages: n/a
Hébergeur: |
David Côme a écrit :
> 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. |
|
|
|
#3 |
|
Messages: n/a
Hébergeur: |
On Sat, 08 Mar 2008 23:41:41 +0100, Michel Decima
<michel.decima@wanadoo.fr> wrote: > David Côme a écrit : >> 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. |
|
![]() |
| Outils de la discussion | |
|
|