Re: Probleme avec istringstream
On Apr 9, 11:25 pm, Michel Decima <michel.dec...@wanadoo.fr> wrote:
> James Kanze a écrit :
> > Rien. Ta chaîne commence bien par un nombre hexadécimal qui a la
> > valeur 14. Si tu veux vérifer que c'est tout ce qu'il
> > contient :
> > if ( iss >> std::hex >> tmp >> std::ws
> > && iss.get() == EOF ) {
> > // c'est bon
> > }
> > Attention, en revanche. J'ai déjà rencontré des manipulateur
> > std::ws qui positionnait failbit s'il était déjà à la fin (parce
> > qu'il construisait un istream::sentry avant de commencer à
> > lire), bien qu'un manipulateur ne doit jamais positionner
> > failbit.
> Le manipulateur ne peut pas positionner failbit, mais est-ce qu'il
> peut positionner eofbit ?
Oui.
En général, je crois qu'on pourrait considérer le eofbit comme
une partie de l'état interne du flux. Pour des raisons diverses,
il y a eu des streambuf qui ne renvoyaient pas forcement EOF une
deuxième fois, quand on appelait sgetc. Pour éviter les
problèmes, alors, l'istream positionne eofflag toujours dès
qu'il voit un eof, et ça, où que ce soit, et n'appelle jamais
plus sgetc/sbumpc/snextc une fois que eofflag positionné. Et la
norme l'exige, plus ou moins. (En fait, la norme n'est pas 100%
claire sur ce qu'elle exige des operator<< écris par
l'utilisateur.)
Du coup, l'utilisation fréquente de eofflag après l'échec, pour
déterminer si l'échec est dû à une erreur de format ou à la fin
du fichier n'est pas 100% fiable. Essaie donc :
std::istringstream s( "1.2E-" ) ;
double d ;
s >> d ;
L'échec est bien dû à une erreur de formattage, et non à la fin
de fichier. Mais eofbit serait quand même positionné.
En fait, il faudrait deux eofflag : un interne, qui signifie
que le streambuf a renvoyé EOF, et qu'on ne doit plus y lire, et
un deuxième, qui signifier que l'échec est dû à la fin de
fichier. Ou simplement rédéfinir eofbit pour servir uniquement
dans le deuxième cas, et exiger que des streambuf::sgetc
successifs doivent toujours renvoyer la même valeur (ce qui est
le cas dans toutes les bonnes implémentations aujourd'hui).
> Je dis ca parce que pour du code similaire a celui ci-dessus,
> j'ai l'habitude de tester eof() plutot que le resultat de
> get():
> if ( iss >> std::hex >> tmp >> std::ws
> && iss.eof() ) {
> // c'est bon
> }
> Ca marche au moins avec g++, mais pour les autres ?
Formellement, je ne crois pas que c'est garantie. Mais je vois
mal comment implémenter ws sans faire du look-ahead, et si ce
look-ahead renvoie EOF, l'eofbit doit être positionné. En
revanche, je ne l'aime pas trop, précisement à cause de toutes
ces ambiguïtés autour de eofbit. Utiliser istream::peek ou
istream::get me semble plus « intuitif ».
--
James Kanze (GABI Software) email:james.kanze@gmail.com
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
|