OVH Cloud OVH Cloud

Flux d'entrée

2 réponses
Avatar
Etienne Rousee
Bonjour,

Pourquoi dans le code suivant, le premier appel a-t-il
besoin de deux retours chariot pour fonctionner ?
(Ensemble est une classe qui contient un vecteur d'entiers
en privé et operator>> est ami de cette classe)
Les appels suivants fonctionnent correctement.

istream& operator>> (istream& is, Ensemble &E)
{
int tmp;

E._Vect.erase(E._Vect.begin(),E._Vect.end());

is.clear();
is.ignore(numeric_limits<streamsize>::max(), '\n' );

while (is >> tmp) E._Vect.push_back(tmp);

return is;
}

--

Etienne

2 réponses

Avatar
James Kanze
Etienne Rousee wrote:

Pourquoi dans le code suivant, le premier appel a-t-il
besoin de deux retours chariot pour fonctionner ?
(Ensemble est une classe qui contient un vecteur d'entiers
en privé et operator>> est ami de cette classe)
Les appels suivants fonctionnent correctement.

istream& operator>> (istream& is, Ensemble &E)
{
int tmp;

E._Vect.erase(E._Vect.begin(),E._Vect.end());

is.clear();
is.ignore(numeric_limits<streamsize>::max(), 'n' );

while (is >> tmp) E._Vect.push_back(tmp);

return is;
}


Parce que typiquement (c-à-d dans toutes les implémentations que
je n'ai jamais vues), les entrées d'un clavier s'effectuent
ligne par ligne -- par défaut, l'implémentation C++ ne voit des
données d'une ligne qu'une fois on a entré la fin de la ligne.
Or, la première chose que tu démandes dans ton opérateur, c'est
que l'implémentation avale tous les caractères jusqu'à ce
qu'elle a vu une fin de ligne. Tant qu'on n'a pas fait un retour
chariot, tu n'avances pas au delà de l'« ignore ». (Par la
suite, probablement, tu n'as pas besoin du retour chariot
supplémentaire parce qu'il en reste un dans le buffer.)

Ceci dit, j'aimerais savoir exactement ce que tu essaies de
faire. Parce que les operator>> qui font clear(), c'est vraiment
inattendu, et risquent de casser pas mal d'autres choses. (Des
operator>> qui font appel à « ignore() » sont assez rares
aussi.)

--
James Kanze (Gabi Software) email:
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

Avatar
Etienne Rousee
"James Kanze" a écrit ...
Etienne Rousee wrote:

Pourquoi dans le code suivant, le premier appel a-t-il
besoin de deux retours chariot pour fonctionner ?
(Ensemble est une classe qui contient un vecteur d'entiers
en privé et operator>> est ami de cette classe)
Les appels suivants fonctionnent correctement.

istream& operator>> (istream& is, Ensemble &E)
{
int tmp;

E._Vect.erase(E._Vect.begin(),E._Vect.end());

is.clear();
is.ignore(numeric_limits<streamsize>::max(), 'n' );

while (is >> tmp) E._Vect.push_back(tmp);

return is;
}


Ceci dit, j'aimerais savoir exactement ce que tu essaies de
faire. Parce que les operator>> qui font clear(), c'est vraiment
inattendu, et risquent de casser pas mal d'autres choses. (Des
operator>> qui font appel à « ignore() » sont assez rares
aussi.)



Quand j'enlève les deux lignes suivantes:
is.clear();
is.ignore(numeric_limits<streamsize>::max(), 'n' );
la première saisie se passe correctement,
c'est à dire que je peux saisir un ensemble sous la forme
2 5 4 1 5 4 2;
par exemple (suite d'entiers séparés par des espaces et terminée
par un caractère différent, ';' n'étant qu'un exemple).
Mais les saisies suivantes sont sautées, ce qui signifie que
le buffer d'entrée n'est pas vide.
Maintenant, le problème semble résolu en faisant une fonction
de ces deux lignes et en l'appelant après le while.

Petite précision qui ne change rien à la chose:
En réalité mes ensembles sont des templates pour pouvoir
faire des ensembles contenant des éléments de n'importe
quel type.

--

Etienne