PHWinfo banniere

Titres
PORTAIL ANNUAIRE ARTICLES COMPARATEUR HÉBERGEURS DEVIS FORUMS RÉDUCTEUR D'URL
Précédent   PHWinfo > Autres forums > Forum Programmation & Conception > fr.comp.lang.c++ > Probleme avec istringstream
S'inscrire FAQ Membres Recherche Messages du jour Marquer les forums comme lus
Probleme avec istringstream

Réponse
 
LinkBack Outils de la discussion
Vieux 08/04/2008, 16h16   #1
Guillaume GOURDIN
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Probleme avec istringstream

Bonjour à tous, j'ai un problème avec le code suivant :

#include <sstream>
#include <iostream>
#include <stdint.h>
using namespace std;

int main(int argc, char ** argv)
{
string s("endor ID Low Byte");
istringstream iss;
uint32_t tmp;

iss.str( s );

if ( !(iss >> hex >> tmp) )
{
return ( false );
}

cout << tmp << endl;

return ( true );
}

Pour ce code, "endor ID Low Byte" est une représentation hexadécimal de
14... Quelqu'un peut-il me dire ce que je fais pas bien?

Merci d'avance!
  Réponse avec citation
Vieux 09/04/2008, 08h19   #2
Michael DOUBEZ
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Probleme avec istringstream

Guillaume GOURDIN a écrit :
> Bonjour à tous, j'ai un problème avec le code suivant :
>
> #include <sstream>
> #include <iostream>
> #include <stdint.h>
> using namespace std;
>
> int main(int argc, char ** argv)
> {
> string s("endor ID Low Byte");
> istringstream iss;
> uint32_t tmp;
>
> iss.str( s );
>
> if ( !(iss >> hex >> tmp) )
> {
> return ( false );
> }
>
> cout << tmp << endl;
>
> return ( true );
> }
>
> Pour ce code, "endor ID Low Byte" est une représentation hexadécimal de
> 14... Quelqu'un peut-il me dire ce que je fais pas bien?


La stream lit le premier "e" qui a la valeur 14 en hexadecimal.

Michael
  Réponse avec citation
Vieux 09/04/2008, 08h47   #3
James Kanze
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Probleme avec istringstream

On Apr 8, 5:16 pm, Guillaume GOURDIN <tr...@hotmail.com> wrote:
> Bonjour à tous, j'ai un problème avec le code suivant :


> #include <sstream>
> #include <iostream>
> #include <stdint.h>
> using namespace std;


> int main(int argc, char ** argv)
> {
> string s("endor ID Low Byte");
> istringstream iss;
> uint32_t tmp;


> iss.str( s );


> if ( !(iss >> hex >> tmp) )
> {
> return ( false );
> }


> cout << tmp << endl;


> return ( true );
> }


> Pour ce code, "endor ID Low Byte" est une représentation
> hexadécimal de 14... Quelqu'un peut-il me dire ce que je fais
> pas bien?


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. Dans ce cas-là (c'était STL port, je crois), la
solution la plus simple, c'est d'écrire toi-même un manipulateur
ws, quelque chose comme :

std::istream&
ws( std::istream& source )
{
if ( source.good() ) {
std::ctype< char > const&
ctype = getFacet( source.getloc() ) ;
std::streambuf* sb = source.rdbuf() ;
int c = sb->sgetc() ;
while ( c != EOF
&& ctype.is( std::ctype_base::space,
static_cast< char >( c ) ) ) {
c = sb->snextc() ;
}
if ( c == EOF ) {
source.setstate( std::ios::eofbit ) ;
}
}
return source ;
}

(Ici, getFacet est plus ou moins std::get_facet, avec des
work-arounds pour d'autres erreurs dans une autre bibliothèque,
et qui renvoie un proxy, de façon à que tu n'aies pas besoin de
répéter le type.)

--
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
  Réponse avec citation
Vieux 09/04/2008, 22h25   #4
Michel Decima
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Probleme avec istringstream

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 ? 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 ?

MD.


  Réponse avec citation
Vieux 10/04/2008, 08h22   #5
Michael DOUBEZ
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Probleme avec istringstream

James Kanze a écrit :
> On Apr 8, 5:16 pm, Guillaume GOURDIN <tr...@hotmail.com> wrote:
>> Bonjour à tous, j'ai un problème avec le code suivant :

>
>> #include <sstream>
>> #include <iostream>
>> #include <stdint.h>
>> using namespace std;

>
>> int main(int argc, char ** argv)
>> {
>> string s("endor ID Low Byte");
>> istringstream iss;
>> uint32_t tmp;

>
>> iss.str( s );

>
>> if ( !(iss >> hex >> tmp) )
>> {
>> return ( false );
>> }

>
>> cout << tmp << endl;

>
>> return ( true );
>> }

>
>> Pour ce code, "endor ID Low Byte" est une représentation
>> hexadécimal de 14... Quelqu'un peut-il me dire ce que je fais
>> pas bien?

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


Je ne comprends pas le problème dans ce cas là:
- si il était déjà à la fin, il positionne failbit et le get suivant
retourne bien EOF. Donc, la stream ne contenait bien que l'entier
- si il n'était pas à la fin, après cela, si la stream est épuisée,
alors get() va de toutes façon positionner failbit.

Michael
  Réponse avec citation
Vieux 10/04/2008, 08h32   #6
Michael DOUBEZ
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Probleme avec istringstream

Michael DOUBEZ a écrit :
> James Kanze a écrit :
>> On Apr 8, 5:16 pm, Guillaume GOURDIN <tr...@hotmail.com> wrote:
>>> Bonjour à tous, j'ai un problème avec le code suivant :

>>
>>> #include <sstream>
>>> #include <iostream>
>>> #include <stdint.h>
>>> using namespace std;

>>
>>> int main(int argc, char ** argv)
>>> {
>>> string s("endor ID Low Byte");
>>> istringstream iss;
>>> uint32_t tmp;

>>
>>> iss.str( s );

>>
>>> if ( !(iss >> hex >> tmp) )
>>> {
>>> return ( false );
>>> }

>>
>>> cout << tmp << endl;

>>
>>> return ( true );
>>> }

>>
>>> Pour ce code, "endor ID Low Byte" est une représentation
>>> hexadécimal de 14... Quelqu'un peut-il me dire ce que je fais
>>> pas bien?

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

>
> Je ne comprends pas le problème dans ce cas là:
> - si il était déjà à la fin, il positionne failbit et le get suivant
> retourne bien EOF. Donc, la stream ne contenait bien que l'entier
> - si il n'était pas à la fin, après cela, si la stream est épuisée,
> alors get() va de toutes façon positionner failbit.


Oups, désolé.
J'ai compris: j'avais pas réalisé qu'il y avait une lecture formatée
dans la logique du if().

Est ce qu'il n'est pas possible alors de faire une logique du type suivant ?

if ( (iss >> std::hex >> tmp) //test formatted input
&& (skipws(iss).get() == EOF) //test unformated input is EOF
)
{
//c'est bon
}

Michael
  Réponse avec citation
Vieux 10/04/2008, 08h37   #7
James Kanze
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut 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
  Réponse avec citation
Vieux 10/04/2008, 08h49   #8
Michael DOUBEZ
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Probleme avec istringstream

Michael DOUBEZ a écrit :
> James Kanze a écrit :
>> On Apr 8, 5:16 pm, Guillaume GOURDIN <tr...@hotmail.com> wrote:
>>> Bonjour à tous, j'ai un problème avec le code suivant :

>>
>>> #include <sstream>
>>> #include <iostream>
>>> #include <stdint.h>
>>> using namespace std;

>>
>>> int main(int argc, char ** argv)
>>> {
>>> string s("endor ID Low Byte");
>>> istringstream iss;
>>> uint32_t tmp;

>>
>>> iss.str( s );

>>
>>> if ( !(iss >> hex >> tmp) )
>>> {
>>> return ( false );
>>> }

>>
>>> cout << tmp << endl;

>>
>>> return ( true );
>>> }

>>
>>> Pour ce code, "endor ID Low Byte" est une représentation
>>> hexadécimal de 14... Quelqu'un peut-il me dire ce que je fais
>>> pas bien?

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

>
> Je ne comprends pas le problème dans ce cas là:
> - si il était déjà à la fin, il positionne failbit et le get suivant
> retourne bien EOF. Donc, la stream ne contenait bien que l'entier
> - si il n'était pas à la fin, après cela, si la stream est épuisée,
> alors get() va de toutes façon positionner failbit.


J'espère que mon message originel est bien annulé. Désolé pour le bruit,
le réveil est dur ce matin.

J'ai compris: j'avais pas réalisé qu'il y avait une lecture formatée
dans la logique du if().

//dans le message originel - code faux

Michael
  Réponse avec citation
Vieux 10/04/2008, 11h44   #9
Olivier Miakinen
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Probleme avec istringstream

Bonjour,

Le 10/04/2008 09:49, Michael DOUBEZ a écrit :
> [ Une cinquantaine de lignes citées ]
>
> J'espère que mon message originel est bien annulé.


Je n'en sais rien. Les articles de toi qui sont visibles, en plus de
celui auquel je réponds, sont celui que tu cites intégralement (il est
donc visible deux fois, sans compter le code initial que tu as cité
intégralement trois fois), plus celui où tu ne répondais qu'une seule
ligne aux trente lignes citées.

> Désolé pour le bruit,


Pour faire un peu moins de bruit, il est recommandé de supprimer de la
citation tout ce qui est superflu pour la compréhension de ta réponse.
Lire <http://www.usenet-fr.net/fur/usenet/repondre-sur-usenet.html>, en
particulier les paragraphes 3a et 3b.

> le réveil est dur ce matin.


Désolé.

--
Olivier Miakinen
  Réponse avec citation
Réponse


Outils de la discussion

Règles de messages
Vous ne pouvez pas créer de nouvelles discussions
Vous ne pouvez pas envoyer des réponses
Vous ne pouvez pas envoyer des pièces jointes
Vous ne pouvez pas modifier vos messages

Les balises BB sont activées : oui
Les smileys sont activés : oui
La balise [IMG] est activée : oui
Le code HTML peut être employé : non
Trackbacks are oui
Pingbacks are oui
Refbacks are oui


Fuseau horaire GMT +1. Il est actuellement 05h43.


Édité par : vBulletin® version 3.7.3
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Search Engine Friendly URLs by vBSEO 3.2.0 RC5 Tous droits réservés.
Version française #16 par l'association vBulletin francophone
PHWinfo est un site Éducation Sans Frontières ©2000-2008
Ad Management by RedTyger
©Tous droits réservés par les parties respectives
Page generated in 0,18914 seconds with 17 queries