cin : comment vérifier la cohérence de l'entrée

cin : comment vérifier la cohérence de l'entrée - C++ - Programmation

Marsh Posté le 18-02-2010 à 15:16:16    

voilà, ne pouvant pas faire de recherche sur les forums avec le mot clé cin... ce sujet est peut-être dupliqué....
 
j'ai une string du type

Code :
  1. MotionNotify: window=0x5000002, root=0x10f, subwindow=0x0, time=704986711, (x,y)=(197,76), (x_root,y_root)=(229,128), state=0x0, is_hint=NotifyHint, same_screen=True


 
dans cette string en utilisant un istream (cin) je veux extraire
MotionNotify 5000002 10f 0 704986711 197 76 229 128 0 NotifyHint True
 
mais je veux aussi faire du strong checking de la chaine : je veux donc que  les chaines  
: window=0x
, root=0x
, subwindow=0x
, time=
, (x,y)=(
,
), (x_root,y_root)=(
,
), state=0x
, is_hint=
, same_screen=
 
soient EXACTEMENT comme cela, je ne veux donc pas faire un simple ignore(int)
je voudrais ainsi faire exactement comme dans scanf mais avec les stream....
sur le net je ne trouve rien... est-ce possible? comment je fais pour ne pas tenir compte des espaces (noskipws?)? dois-je faire le check à la main? cad lire une std::string en lui donnant une taille et puis après vérifier que c'est la bonne chaine attendu?
on dit que les cin/cout du c++ sont bien meilleurs que leurs équivalents C.... n'empèche que je ne trouve nul part comment faire cette fonctionnalité de manière simple
merci d'avance
JL

Reply

Marsh Posté le 18-02-2010 à 15:16:16   

Reply

Marsh Posté le 18-02-2010 à 18:49:43    

- getline pour choper toute la ligne
- boost::tokenizer sur "," avec un escaped_list_separator sur "()"
peut-être un separator maison avec une notion d'ouverture et de fermeture (pour être safe contre " )(" ).
=> ça te donne les paires "propriétées = valeur"
tu peux ensuite refaire une passe de tokenizer pour les séparer et vérifier la cohérence de la valeur.


Message édité par bjone le 18-02-2010 à 18:53:16
Reply

Marsh Posté le 18-02-2010 à 23:20:55    

Sinon ce qui peut bien marcher pour faire quelque chose comme ca c'est de passer par boost::spirit. cela va te permettre de faire l'analyse tout simplement.
 
jette un œil a la doc:
http://www.boost.org/doc/libs/1_42 [...] index.html

Reply

Marsh Posté le 19-02-2010 à 00:23:45    

merci, mais j'aimerai autant que possible ne pas utiliser boost.... ces classes sont très cool, mais trop lourdes pour mon utilisation... soit je vais passer par getline(istream, string) puis par sscanf.... soit je vais faire ma propre class dérivée de istream avec un operator>> pouvant prendre un const std::string en paramètre (qui ferait une lecture non formatée de la n caractères et vérifierai après coup) néanmoins avec tout ce que disent les pro-c++ comme quoi les istream c'est mieux que scanf.... et ben je pense qu'ils n'ont jamais fait autre chose que des programmes du style
cout<<"quel est ton nom?"
cin >> nom

Reply

Marsh Posté le 19-02-2010 à 07:01:54    

cityhunterxyz a écrit :


merci, mais j'aimerai autant que possible ne pas utiliser boost.... ces classes sont très cool, mais trop lourdes pour mon utilisation... soit je vais passer par getline(istream, string) puis par sscanf.... soit je vais faire ma propre class dérivée de istream avec un operator>> pouvant prendre un const std::string en paramètre (qui ferait une lecture non formatée de la n caractères et vérifierai après coup)


Non, tu fais des entrees structurees non triviales, l'outil adequat est un mini parser. Donc spirit vu que c'est a peu pres le seul et meilleur truc de disponible. Apres cacher ta flemme derriere l'excuse que 'boost c'est lourd', c'est ton probleme.

 

D'ailleurs:

 

http://boost-spirit.com/home/artic [...] spirit-qi/

 

repond partiellement a ton probleme. Apre, clairement 8 lignes c'est lourd :o

 
cityhunterxyz a écrit :


néanmoins avec tout ce que disent les pro-c++ comme quoi les istream c'est mieux que scanf.... et ben je pense qu'ils n'ont jamais fait autre chose que des programmes du style
cout<<"quel est ton nom?"
cin >> nom


On utilise le bon outil pour le bon probleme, c'est tout. Mais je pense que ta grande experience du c++ te donne le droit d'avoir un avis moisi ...

 

On m'excusera du manque de :o mais il est un peu tot :o


Message édité par Joel F le 19-02-2010 à 07:02:36
Reply

Marsh Posté le 19-02-2010 à 10:52:57    

pour m'être occupé du packaging et de la compilation d'une distribution linux basée sur les sources je connais assez bien boost... et vu le travail que ce dernier m'a généré à chaque nouvelle release, je pense que je vais m'en passer... en outre je ne veux pas un parser syntaxique, je veux du strong checking => si le format n'est pas STRICTEMENT identique je veux une ERREUR. *scanf le permet... quand à "l'avis moisi" je vais te demander pourquoi il faut passer par boost pour faire une fonctionalité qui est de base dans du C? :lol:  
 
quand à 8 lignes c'est lourd.... cela me fait bien rire! attends oui le développeur n'a que 8 lignes à mettre... l'utilisateur qui va compiler tout cela, lui, aura le droit de se taper toute la merde pour installer les dépendences et au vu du fait que chaque nouvelle release de boost entraine la non compilation de la quasi totalité des outils l'utilisant.... Je veux un minimum de dépendences...
boost c'est cool! mais les développeurs de boost n'ont JAMAIS réfléchi au problème de l'intégration de leur code...

Reply

Marsh Posté le 19-02-2010 à 11:55:43    

cityhunterxyz a écrit :


pour m'être occupé du packaging et de la compilation d'une distribution linux basée sur les sources je connais assez bien boost... et vu le travail que ce dernier m'a généré à chaque nouvelle release, je pense que je vais m'en passer... en outre je ne veux pas un parser syntaxique, je veux du strong checking => si le format n'est pas STRICTEMENT identique je veux une ERREUR. *scanf le permet... quand à "l'avis moisi" je vais te demander pourquoi il faut passer par boost pour faire une fonctionalité qui est de base dans du C? :lol:  


bah te casses pas fait du C et arretes de chouiner sur des trucs que tu ne maitrises pas :o
Sinon, regarde boost::regex ou bosot::format :o Bref sors toi les doigts.
 

cityhunterxyz a écrit :


quand à 8 lignes c'est lourd.... cela me fait bien rire! attends oui le développeur n'a que 8 lignes à mettre... l'utilisateur qui va compiler tout cela, lui, aura le droit de se taper toute la merde pour installer les dépendences et au vu du fait que chaque nouvelle release de boost entraine la non compilation de la quasi totalité des outils l'utilisant.... Je veux un minimum de dépendences...
boost c'est cool! mais les développeurs de boost n'ont JAMAIS réfléchi au problème de l'intégration de leur code.


 
Fichtre ca se voit qu'on est vendredi :o
 
Si:
 

Code :
  1. cd boost && ./bootstrap && ./bjam install


 
c'est compliqué, je vois pas ce qui les sauveras.  
C'est pas pire qu'installer un package linux foireux comme linux c'est si bien les faire :o

Reply

Marsh Posté le 19-02-2010 à 12:12:52    

installer boost c'est une chose... je te conseille d'aller essayer de l'utiliser dans un env réel (cad un env où tu upgrade boost et tu recompiles les softs qui en dépendent) et après on en reparle....  
 
JE NE VEUX PAS DE BOOST! c'est dur à comprendre ou bien il faut t'acheter un cerveau? Les seules dépendances que je m'autorise sont la libc, la stdlib, et opengl

Reply

Marsh Posté le 19-02-2010 à 12:14:42    

cityhunterxyz a écrit :


installer boost c'est une chose... je te conseille d'aller essayer de l'utiliser dans un env réel (cad un env où tu upgrade boost et tu recompiles les softs qui en dépendent) et après on en reparle....  
l


 
C'est ce que je fais tout le temps au boulot [:smiley avec un café]
 

cityhunterxyz a écrit :


JE NE VEUX PAS DE BOOST! c'est dur à comprendre ou bien il faut t'acheter un cerveau? Les seules dépendances que je m'autorise sont la libc, la stdlib, et opengl


Bah, scanf et point :o

Reply

Marsh Posté le 19-02-2010 à 13:58:31    

bon ben merci, c'est l'information que je recherchais.... savoir si avec la stdlib on pouvait faire ce que je voulais faire... ceci réponds à ma question....
désolé de m'être emporté mais répondre à quelqu'un "t'as qu'a utiliser ...." alors qu'il cherche à savoir si dans tel lib la fonctionalité existe... j'ai mes raisons pour ne pas vouloir utiliser boost... c'est comme les gens qui disent 't'as qu'a le faire en QT" alors que l'application que tu veux faire consiste en 3 boutons et une zone de texte (soit un programme de 100K compilé à tout casser, qui se link avec une lib de 50Mo) je veux rester le plus léger possible et le plus simple aussi
donc je vais essayer autre chose... et me rabattre sur scanf si pas d'autre choix... mais au final je reste sur ma position : les iostream C++ c'est m......e

Reply

Marsh Posté le 19-02-2010 à 13:58:31   

Reply

Marsh Posté le 19-02-2010 à 14:16:16    

cityhunterxyz a écrit :

bon ben merci, c'est l'information que je recherchais.... savoir si avec la stdlib on pouvait faire ce que je voulais faire... ceci réponds à ma question....
désolé de m'être emporté mais répondre à quelqu'un "t'as qu'a utiliser ...." alors qu'il cherche à savoir si dans tel lib la fonctionalité existe... j'ai mes raisons pour ne pas vouloir utiliser boost... c'est comme les gens qui disent 't'as qu'a le faire en QT" alors que l'application que tu veux faire consiste en 3 boutons et une zone de texte (soit un programme de 100K compilé à tout casser, qui se link avec une lib de 50Mo) je veux rester le plus léger possible et le plus simple aussi
donc je vais essayer autre chose... et me rabattre sur scanf si pas d'autre choix... mais au final je reste sur ma position : les iostream C++ c'est m......e


Oui sauf que QT n'est pas considéré comme le quasi standard de l'interface graphique... Donc comparaison foireuse. De plus la majeure partie de boost ne demande pas de lib (de 50Mo ou moins).
On ne dit pas "c'est m......e" mais "ça ne fait pas ce que je pensais".

 

edit: les méthodes de la classe string doivent pouvoir te permettre de rechercher une sous-chaîne comme par exemple "window=0x". Ce n'est pas ça que tu recherches? Tu obtiens la position et tu peux ensuite extraire le nombre qui suit.

Message cité 1 fois
Message édité par ptitchep le 19-02-2010 à 14:29:47

---------------
deluser --remove-home ptitchep
Reply

Marsh Posté le 19-02-2010 à 15:38:21    

ptitchep a écrit :


Oui sauf que QT n'est pas considéré comme le quasi standard de l'interface graphique... Donc comparaison foireuse. De plus la majeure partie de boost ne demande pas de lib (de 50Mo ou moins).
On ne dit pas "c'est m......e" mais "ça ne fait pas ce que je pensais".
 
edit: les méthodes de la classe string doivent pouvoir te permettre de rechercher une sous-chaîne comme par exemple "window=0x". Ce n'est pas ça que tu recherches? Tu obtiens la position et tu peux ensuite extraire le nombre qui suit.


 
Oui il fait un parseur maison.
 
La solution du scanf est hyper rigide et peut rapidement déconner dès qu'un pattern différent est rencontré.
 
Donc si il veut faire un truc bourrinos pas fini va pour le scanf, si il veut faire un truc qui permet d'avoir des collections de clés/valeur dynamiques qu'il peut manipuler, faut un parseur flexible.
 
Et puis 70% des fonctionnalités de boost sont des templates.
Perso c'est pas rare que j'attrape que les headers de boost pour les mettre dans un répertoire du svn du projet, juste pour simplifier les dépendances.


Message édité par bjone le 19-02-2010 à 15:41:54
Reply

Marsh Posté le 19-02-2010 à 18:45:56    

sauf que  
1) boost n'est le quasi standard que de ceux qui veulent le considérer tel... tout comme QT, GTK, windows ou plein d'autres trucs sont le standard de quelqu'un
2) je ne cherche pas à faire un truc flexible car les chaines sont des dumps d'evènements X11, le parseur ne fait que rejouer la séquence, il ne faut justement pas qu'il y ai une quelconque flexibilité, pas de place à une quelconque improvisation, toutes les données doivent être présente et justement je ne veux pas que l'utilisateur fasse n'importe quoi... je veux donc un truc RIGIDE qui s'arrêtera à la moindre erreur
3) je voulais éviter de faire diverger le loggeur (ostream et << ) du lecteur... donc voilà pourquoi scanf ne me plait pas trop
4) je ne comprends pas comment on a pu créer un standard qui ne tienne pas compte du fait que l'on puisse vouloir faire un truc du style
cin >> "mon nom est" >> nom >> "mon age est" >> age;

Message cité 1 fois
Message édité par cityhunterxyz le 19-02-2010 à 18:46:45
Reply

Marsh Posté le 19-02-2010 à 19:12:17    

Pour répondre au 1/ boost c'est l'antichambre de la std et pas mal de morceaux ont déjà ete incorporé dans la std tr 1 :o

Reply

Marsh Posté le 19-02-2010 à 19:50:55    

cityhunterxyz a écrit :

sauf que
1) boost n'est le quasi standard que de ceux qui veulent le considérer tel... tout comme QT, GTK, windows ou plein d'autres trucs sont le standard de quelqu'un


Joel F a écrit :

Pour répondre au 1/ boost c'est l'antichambre de la std et pas mal de morceaux ont déjà ete incorporé dans la std tr 1 :o

 

Tout ce qui est dans boost n'a pas vocation à être standardisé -- même tout TR1 ne sera pas repris dans la norme.

 
cityhunterxyz a écrit :


2) je ne cherche pas à faire un truc flexible car les chaines sont des dumps d'evènements X11, le parseur ne fait que rejouer la séquence, il ne faut justement pas qu'il y ai une quelconque flexibilité, pas de place à une quelconque improvisation, toutes les données doivent être présente et justement je ne veux pas que l'utilisateur fasse n'importe quoi... je veux donc un truc RIGIDE qui s'arrêtera à la moindre erreur

 

Alors je me demande si scanf ne présente trop de flexibilité dans sa gestion des espaces.

 
Citation :

3) je voulais éviter de faire diverger le loggeur (ostream et << ) du lecteur... donc voilà pourquoi scanf ne me plait pas trop


Fait toi une libraire fonctionnant sur le même principe que certaines lib de sérialisation.

 
Citation :

4) je ne comprends pas comment on a pu créer un standard qui ne tienne pas compte du fait que l'on puisse vouloir faire un truc du style
cin >> "mon nom est" >> nom >> "mon age est" >> age;

 

Parce que personne n'a trouvé ça assez important pour faire une proposition -- sans parler de réussir à convaincre le commité que c'était utile.

Message cité 1 fois
Message édité par Un Programmeur le 19-02-2010 à 19:52:34

---------------
The truth is rarely pure and never simple (Oscar Wilde)
Reply

Marsh Posté le 19-02-2010 à 21:00:27    

Un Programmeur a écrit :


sans parler de réussir à convaincre le commité que c'était utile.


 
surtout  :sweat:  

Reply

Marsh Posté le 21-02-2010 à 00:17:47    

quelque chose : language-independent!
 
on a ca :
MotionNotify: window=0x5000002, root=0x10f,
subwindow=0x0, time=704986711,
(x,y)=(197,76),
(x_root,y_root)=(229,128), state=0x0,
is_hint=NotifyHint, same_screen=True
 
on veut ca :  
MotionNotify 5000002 10f 0 704986711 197 76 229 128 0 NotifyHint True
 
mapper a ca:
hex, hex, hex, decimal, vector/point , hex
 
une function qui verife chaque type ( 3 function ou plus)
 
- un titre 'MotionNotify' s'arrete avec ':'
- n tokens  : For Each token :  verify() + print() ou cat()
 
if FAILED(verify()) { shutdown -h now }  :lol:  
 
tu peut meme chercher autre language.
 
[ commentez comme vous voulez !  :pt1cable: ]

Reply

Marsh Posté le 21-02-2010 à 12:08:19    

:sol:  mais ca c'est an XPointerMovedEvent struct  
(notification qui rapporte le movement du souris)
 
normalement tu recoie une structure , avec des type
fix (ici pourquoi ce STRONG checking ?)
et puis tu convert chaque type en string avec quelque formatage
puis tu echo  
 
si tu veux faire une base de donnees (ou un archive)
avec ces notification de XServer
ca c'est une autre chose !
 
merci.

Reply

Marsh Posté le 21-02-2010 à 15:42:09    

c'est un moyen d'automatiser mes tests de mon GUI... je sauvegarde les traces (je veux donc que ce soit human readable pour pouvoir être sur de ce que j'ai obtenu) et je suis en train d'écrire le re-player
 
j'ai fait ma solution en créant un opérateur

Code :
  1. std::istream& operator>> (std::istream& str, const char* format);


je suis en train de le débugger et je posterais ma solution après vérification, en tout cas cela compile...

Reply

Marsh Posté le 21-02-2010 à 16:40:53    

il existe deja. Je serais toi, je prendrais un objet Format en parametere, ca evitera d'avoir un comportement incoherent par moment.

Reply

Marsh Posté le 21-02-2010 à 22:02:36    

il n'exite pas... si je ne le défini pas j'ai un horrible message d'erreurs me proposant plein d'opérateurs mais pas celui là
ce qui est confirmé par http://www.cplusplus.com/reference [...] tor%3E%3E/

Reply

Marsh Posté le 21-02-2010 à 22:10:46    

char* ^ ^ le défini doit etre std::string.

Reply

Marsh Posté le 22-02-2010 à 00:06:14    

c'est pas un char* que je cherche. c'est un const char*

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed