OVH Cloud OVH Cloud

au sujet d un acces curieux a un string ...

156 réponses
Avatar
ricky
bonjour

j ai de nouveau un chtti truc etrange !

je fais quelquechose comme :
int main()
{
string pattern;
...
cout << "entrez le pattern";
cin >> pattern;
cin.get(); // pour virer le enter du buffer pour apres

balayage cache
recherche du pattern
affochage
}

ok tout marche super

je rajoute juste un truc :
...
cin.get();

cout << pattern[0];
...

donc juste un affichage du premier caractere, un truc bien neutre quoi

et la , la recherche echoue et donne 0 resultats !!!

quelque soit le code de recherche, en quoi le simple fait d afficher le
premier caractere d une string peut il changer quoique ce soit ?????

une idee ? :-)

@+
ricky... je sais pas si les reveillons me reussissent moi :)

10 réponses

1 2 3 4 5
Avatar
Fabien LE LEZ
On Sat, 27 Dec 2003 01:38:14 +0100, ricky wrote:

string pattern;


J'imagine qu'il y a un "using namespace std;" quelque part ?
J'aime pas trop ça, mais bon, pour un petit programme de test,
pourquoi pas...

...
cout << "entrez le pattern";



cin >> pattern;
cin.get(); // pour virer le enter du buffer pour apres


Encore une technique que je n'aime pas. Le "cin >> pattern" s'arrête
dès qu'un espace est rencontré, et le reste, ben... il reste en
attente dans le buffer. En pratique, c'est assez rarement l'effet
escompté.
Perso, j'utilise systématiquement std::getline(), et je parse la ligne
lue si nécessaire.


cout << pattern[0];


Tu ne t'es pas assuré que pattern[0] existe, i.e. que
pattern.size()>0.

donc juste un affichage du premier caractere, un truc bien neutre quoi

et la , la recherche echoue et donne 0 resultats !!!

quelque soit le code de recherche, en quoi le simple fait d afficher le
premier caractere d une string peut il changer quoique ce soit


AMHA, tu as un code à comportement indéfini quelque part (accès à un
élément inexistant, double appel de delete sur le même pointeur,
etc.), ce qui donne un comportement erratique, qui peut être
grandement modifié par un code qui normalement ne change rien.
Essaie de simplifier au maximum ton code (tout en conservant le
problème), et poste un code complet (=compilable) mais court ici, on
arrivera sans doute à détecter un ou deux problèmes.

?????


Tiens, ta touche "?" est coincée.

--
;-)

Avatar
ricky
bonjour

J'imagine qu'il y a un "using namespace std;" quelque part ?


oui tout a fait

J'aime pas trop ça, mais bon, pour un petit programme de test,
pourquoi pas...


le using namespace?

Encore une technique que je n'aime pas. Le "cin >> pattern" s'arrête
dès qu'un espace est rencontré, et le reste, ben... il reste en
attente dans le buffer. En pratique, c'est assez rarement l'effet
escompté.


dans mon cas ca va, ce sont des mots seuls :)

Perso, j'utilise systématiquement std::getline(), et je parse la ligne
lue si nécessaire.


ah ... pourquoi pas !

Tu ne t'es pas assuré que pattern[0] existe, i.e. que
pattern.size()>0.


dans mon cas, je rentre bien une reponse donc pour mon test j en suis
assure

AMHA, tu as un code à comportement indéfini quelque part


zut j avais pas pense a ca ...
bon je vais cherche... merci a toi !

Tiens, ta touche "?" est coincée.


nonnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn elle est
debloqueeeeeeeeeeeeeee.. c est de la faute au cout lol

@+
ricky

Avatar
Fabien LE LEZ
On Sat, 27 Dec 2003 03:33:24 +0100, ricky wrote:

Encore une technique que je n'aime pas. Le "cin >> pattern" s'arrête
dès qu'un espace est rencontré, et le reste, ben... il reste en
attente dans le buffer. En pratique, c'est assez rarement l'effet
escompté.


dans mon cas ca va, ce sont des mots seuls :)


Mais comment peux-tu prévoir ce que l'utilisateur tapera ?
La règle de base de l'interface utilisateur, c'est que le programme
fonctionnera le mieux possible quoi que l'utilisateur fasse.

Tu as choisi de faire un programme interactif en mode console (ce que
je ne fais quasiment jamais personnellement). Le programme sera bloqué
tant que l'utilisateur ne tape pas "Entrée", et toute la ligne est
alors rendue disponible pour cin. Il faut donc s'assurer que tous les
caractères seront lus avant la prochaine demande de saisie ; le moyen
le plus simple pour s'en assurer est d'utiliser getline().

Tu ne t'es pas assuré que pattern[0] existe, i.e. que
pattern.size()>0.


dans mon cas, je rentre bien une reponse donc pour mon test j en suis
assure


Si c'est juste un petit test, tu peux effectivement te contenter de
rajouter un commentaire du style "Attention, test de validité non
effectué". Mais bon, assure-toi de ne pas laisser longtemps un tel
code dans ton programme, sinon tu finiras par oublier que tu as du
code dangereux, et passer des heures à essayer de repérer l'origine
d'un bug bizarre :-(

lol


C'est lol un lol nouveau lol genre lol d'expression lol de lol taper
"lol" un peu partout lol ?
Rappel : fr.comp.lang.c++ est un forum francophone.

--
;-)


Avatar
ricky
bonjour

Mais comment peux-tu prévoir ce que l'utilisateur tapera ?


parcequ il y en a pas pour ce code a part moi :-)

La règle de base de l'interface utilisateur, c'est que le programme
fonctionnera le mieux possible quoi que l'utilisateur fasse.


oui je suis d accord avec toi

Tu as choisi de faire un programme interactif en mode console (ce que
je ne fais quasiment jamais personnellement).


tu fais quoi ?


Le programme sera bloqué
tant que l'utilisateur ne tape pas "Entrée",


oui

et toute la ligne est
alors rendue disponible pour cin.


oui

Il faut donc s'assurer que tous les
caractères seront lus avant la prochaine demande de saisie ; le moyen
le plus simple pour s'en assurer est d'utiliser getline().


oui c est note, et je compte l utiliser

Si c'est juste un petit test, tu peux effectivement te contenter de
rajouter un commentaire du style "Attention, test de validité non
effectué".


oui c est un programme perso poru moi celui la, pour m aider dans les
mots croises

Mais bon, assure-toi de ne pas laisser longtemps un tel
code dans ton programme, sinon tu finiras par oublier que tu as du
code dangereux, et passer des heures à essayer de repérer l'origine
d'un bug bizarre :-(


hum comme celui que j ai quoi !

C'est lol un lol nouveau lol genre lol d'expression lol de lol taper
"lol" un peu partout lol ?


je n'en ai pas mis partout !!!
j indiquais simplement que cela me faisait rire

Rappel : fr.comp.lang.c++ est un forum francophone.


rappel : les emoticons et autres termes permettant d indiquer une
expression, humeur ne sont pas relies a une langue particuliere ^_^
rappel1 : on ne dit pas bug mais bogue en francophonie lol
et lol est plus connu que mdr :-)
rappel2 : ne pas s offusquer de mes rappel, je deconne, je suis
fatiguuuuueeeeeee !!!

@+
ricky

Avatar
James Kanze
ricky writes:

|> j ai de nouveau un chtti truc etrange !

|> je fais quelquechose comme :
|> int main()
|> {
|> string pattern;
|> ...
|> cout << "entrez le pattern";
|> cin >> pattern;
|> cin.get(); // pour virer le enter du buffer pour apres

|> balayage cache
|> recherche du pattern
|> affochage
|> }

|> ok tout marche super

|> je rajoute juste un truc :
|> ...
|> cin.get();

|> cout << pattern[0];
|> ...

|> donc juste un affichage du premier caractere, un truc bien neutre quoi

|> et la , la recherche echoue et donne 0 resultats !!!

|> quelque soit le code de recherche, en quoi le simple fait d afficher
|> le premier caractere d une string peut il changer quoique ce soit ?????

|> une idee ? :-)

C'est typiquement un symptome d'un cas où on se sert d'une variable
qui n'existe plus. Tu ne nous montres pas le code du balayage, etc., et
je vois mal comment ça pourrait être un problème avec le bout
du code que tu nous montres (mais est-ce qu'il est réelement conforme
à ce que tu as écris), mais un exemple typique d'où ce genre de
problème se présent, c'est quand le pattern serait une variable
locale dans une fonction, et que tu en renvoies une référence.
C'est un comportement indéfini, mais typiquement, la variable serait
sur la pile, même après le retour, et tant que tu n'appelles pas
d'autre fonction. (Dans le cas de string, la mémoire dynamique dont
il se sert serait libéré, mais là aussi, typiquement, des
accès en fonctionnerait jusqu'à la prochaine allocation, sinon au
delà.) Le « cout << pattern[ 0 ] », évidemment, contient
l'appel qui écrase les valeurs anciennement sur la pile.

--
James Kanze mailto:
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France +33 1 41 89 80 93
Avatar
ricky
bonjour

C'est typiquement un symptome d'un cas où on se sert d'une variable
qui n'existe plus. Tu ne nous montres pas le code du balayage, etc., et


d acord, je vais cherchr et si je trouve pas je donnerais plus de code...

mais un gag, pour utiliser le cin.getline(), j'ai change le string
pattern en char patern[256], et la je n'ai plus aucun probleme :-)
mais bon ca ne me satisfait pas !

sinon en premiere verification, la variable etant definie dans le main,
puis passee a la procedure de recherche par copie, je ne vois pas
comment elle pourrait etre supprimee !

en fait j appel un truc comme :
int Mot::comparaison (string pattern)
{
si( pattern[i] == mot[i])
...
return OK;
ou return ECHEC;
}
bref cette procedure ne touche a rien !

bon je vais y retourner voir ce gag

@+
ricky

Avatar
ricky
merci a tous pour vos precieuses explications

a titre d info "erreur debutant" avec consequences bizarres, j'ai trouve
le pourquoi du comment !
je le met ici pour clore ma demande meme si ca doit pas servir a grand
monde :-)

C'est typiquement un symptome d'un cas où on se sert d'une variable
qui n'existe plus.


presque :-)
mais j enreistre aussi ce gag possible la prochaine fois que j'ai un
comportement "indefini"

Tu ne nous montres pas le code du balayage,


c etait bien lui le responsable en effet :-)
comme il n'y avait aucune ecriture dans ce code, je ne pensais pas qu'il
pouvait etre responsable d un quelconque effet de bord ...


je vois mal comment ça pourrait être un problème avec le bout
du code que tu nous montres


oui et non !
en fait, selon le type du pattern (char* ou string) tout changeait !

en fait, dans le balayage des chaines, il se trouve que j'allais 1 cran
au dela de la chaine ( while (ptrMot <= logueurMot) ... )
ce qui m'a fait tilter, c est que le code a fontionne quand je suis
passe en char* au lieu de string

j'en deduit que la comparaison marchait avec les char* car le caractere
au dela de la chaine devait etre le delimiteur , et donc la
comparaison se passait bien quelque soit le cas.

dans le cas d'une string, comme je ne crois pas qu'il y ait de
delimiteur (il me semble qu'il y a la taille de la string dans l objet
et que le char* ne contient que l'utile), le comportement devait etre
indefini, dependant de ce qu'il devait y avoir en memoire.

le code marchait bien quand je ne regardait pas le pattern[] (ce qui est
finalement etonnant !), mais echouait en cas contraire !
j'aurais prefere qu'il echoue dans tous les cas :-)

delà.) Le « cout << pattern[ 0 ] », évidemment, contient
l'appel qui écrase les valeurs anciennement sur la pile.


la cela reste un peu un mystere pour moi, meme si je comprend bien que
la memoire peut etre reutilisee !!!

si je faisait un cout << pattern, pas de blem
c'est uniquement quand j utilisait pattern[x] que cela echouait !
je pouvais faire n importe quoi d'autre, pas de probleme !

je ne comprend toujours pas en quoi ce pattern[x] changeait quoique ce
soit au caractere qui suivait le string ! mais je pense que ton
explication doit aussi pouvoir s'appliquer dans ce cas...

je pensais quand meme que "pattern[0]" etait juste l'acces a une case
memoire, et donc que cela ne changeait aucune allocation ou valeur nulle
part ! il n'y pas d'ecriture, ni de definition de variable la !

mais bon, c est surement normal pour un comportement non defini d'etre
... indefini :-)

@+
ricky

Avatar
Fabien LE LEZ
On Sat, 27 Dec 2003 05:58:39 +0100, ricky wrote:

On Sat, 27 Dec 2003 05:58:39 +0100, ricky wrote:

Mais comment peux-tu prévoir ce que l'utilisateur tapera ?


parcequ il y en a pas pour ce code a part moi :-)


Mais tu comptes ne l'utiliser que dans les prochaines heures, et le
jeter après, ou tu comptes l'utiliser à nouveau dans quelques mois,
quand tu auras tout oublié de tels détails ?

Tu as choisi de faire un programme interactif en mode console (ce que
je ne fais quasiment jamais personnellement).


tu fais quoi ?


Soit des programmes en mode console qui lisent leurs données dans un
ou plusieurs fichiers de config et/ou sur la ligne de commande, soit
des programmes GUI.

Mais bon, assure-toi de ne pas laisser longtemps un tel
code dans ton programme, sinon tu finiras par oublier que tu as du
code dangereux, et passer des heures à essayer de repérer l'origine
d'un bug bizarre :-(


hum comme celui que j ai quoi !


C'est effectivement possible ;-)



[lol]
je n'en ai pas mis partout !!!


Ma réaction vient d'une très forte impression que taper "lol" devient
un tic chez certains, en oubliant que cet acronyme a un sens assez
fort.

j indiquais simplement que cela me faisait rire


Hurler de rire, plus exactement (c'est ce que signifie "lol").

Rappel : fr.comp.lang.c++ est un forum francophone.


rappel : les emoticons et autres termes permettant d indiquer une
expression, humeur ne sont pas relies a une langue particuliere


Comme le smiley qui est mis automatiquement dans ma signature ? ;-)

[Note : un jour, sur fr.rec.anime, un gars a pris sérieusement ce que
je croyais être une plaisanterie. C'est depuis que j'ai mis un smiley
en signature, pour encourager mes lecteurs à prendre tous mes posts
avec un recul suffisant ;-) ]

^_^


Oh, un smiley japonais[*]. Décidément, ce thread est multilingue ^^

[*] ou asiatique ?

rappel2 : ne pas s offusquer de mes rappel, je deconne, je suis
fatiguuuuueeeeeee !!!


C'est à force de taper "lol", ça fatigue !

--
;-)


Avatar
ricky
hello

Mais tu comptes ne l'utiliser que dans les prochaines heures, et le
jeter après, ou tu comptes l'utiliser à nouveau dans quelques mois,
quand tu auras tout oublié de tels détails ?


ben c est un programme ou l'entree est seulement un mot :-)
c'est unen aide pour mes mots croises :-)
donc, comme il n'y a pas d espace dans un mot, pas de blem meme dans
plusieurs mois !
euh pardon : lol !

Soit des programmes en mode console qui lisent leurs données dans un
ou plusieurs fichiers de config et/ou sur la ligne de commande, soit
des programmes GUI.


ben c est pour entrer un mot, au moment ou cela me chante, donc pas de
fichier de config...
ensuite, GUI, je veux bien, mais bon ... il faut que je me mette a
wxwindows pour ca amha ...

C'est effectivement possible ;-)


m enfiche, c est resolu .. grace a vous quand meme :-)

Ma réaction vient d'une très forte impression que taper "lol" devient
un tic chez certains, en oubliant que cet acronyme a un sens assez
fort.


meuh non, c est surtout le bruit qui est fort, pas le sens :-)

Hurler de rire, plus exactement (c'est ce que signifie "lol").


oui ... ou rire fortement, ca suffit , j'ai des voisins quand meme !

Comme le smiley qui est mis automatiquement dans ma signature ? ;-)


il en perd sa valeur, aucun de tes messages ne peut donc etre pris au
serieux !
rappel : ne jamais mettre un smiley en variable globale, il peut y avoir
des effets de bord sur tout le programme, les humains ne gerant que
rarement les variables locales :-)

Oh, un smiley japonais[*]. Décidément, ce thread est multilingue ^^

[*] ou asiatique ?


issu des masques de theatre japonais en effet :-)
c'est donc ausi asiatique en quelque sorte !

C'est à force de taper "lol", ça fatigue !


nan, mais de compiler avec un langage a la noix, qui ne possede pas de
gui, pas d acces simple aux droits, repertoires, contenus, pas d'input
correct, (alors que d autres langages normalises eux aussi ont tout ca,
merci java , tcl, python, etc) et que j'adore en plus (etant un vieux
crouton du c)....

PS : euh un chtit troll s'est cache quelquepart dans ce message, priere
de ne pas le taper trop fort

Avatar
Fabien LE LEZ
On Sun, 28 Dec 2003 01:30:39 +0100, ricky wrote:

c'est unen aide pour mes mots croises :-)
donc, comme il n'y a pas d espace dans un mot, pas de blem meme dans
plusieurs mois !


Justement, certains mots de mots croisés sont composés, et contiennent
des espaces (même s'ils n'apparaissent pas sur la grille, ou sont
seulement matérialisés par des barres plus épaisses).

il en perd sa valeur, aucun de tes messages ne peut donc etre pris au
serieux !


Aucun message de ma part ne doit être pris sans un certain recul, en
tout cas.

nan, mais de compiler avec un langage a la noix, qui ne possede pas de
gui


Plus exactement, un langage qui laisse le programmeur choisir sa
bibliothèque GUI ;-)
C++ est un langage qui laisse énormément de libertés au programmeur...
y compris la liberté de faire des conneries.
Quand à l'expression "langage à la noix", c'est pas totalement faux :
C++ doit une partie de sa popularité au fait qu'il est basé sur le C,
mais c'est aussi (paradoxalement) son plus gros défaut.

--
;-)

1 2 3 4 5