OVH Cloud OVH Cloud

std::cin le retour

5 réponses
Avatar
Ultimataupe
Voici mon programme:

//utilisation sous Visual C++ 6
int main(int argc, char* argv[])
{
int i = 0;
while ( i != 1)
{
std::cout << "tapez 1" << std::endl;
std::cin >> i ;
}
std::cout << "bravo" << std::endl;

return 0;
}

Voici mon probleme:
si j'entre des lettres à la place des chiffres ça boucle sans fin.
Comment reinitialiser cin ?
(j'ai essayé un clear() mais sans succes).

Merci à tous.

5 réponses

Avatar
Alexandre
Voici mon probleme:
si j'entre des lettres à la place des chiffres ça boucle sans fin.
Comment reinitialiser cin ?
(j'ai essayé un clear() mais sans succes).


de mémoire : cin.sync()


Merci à tous.


Avatar
kanze
Ultimataupe wrote:
Voici mon programme:

//utilisation sous Visual C++ 6
int main(int argc, char* argv[])
{
int i = 0;
while ( i != 1)
{
std::cout << "tapez 1" << std::endl;
std::cin >> i ;
}
std::cout << "bravo" << std::endl;

return 0;
}

Voici mon probleme:

si j'entre des lettres à la place des chiffres ça boucle sans
fin. Comment reinitialiser cin ? (j'ai essayé un clear()
mais sans succes).


C'est bien clear() qu'il te faut, mais quand le flux a détecter
les lettres, il ne les a pas extraits. Alors, la prochaine fois
dans la boucle, il les rétrouve, et se met en erreur de nouveau.

C'est un problème général lors de l'interprétation des données
en entrée : comment résynchroniser en cas d'erreur. Dans ton
cas, il faut comme minimum lire (extraire) le caractère qui a
provoqué l'erreur (cin.get()). La plupart du temps quand on lit
cin, en revanche, on pense à des entrées interactives, ligne par
ligne. Dans ce cas-là, la fonction cin.ignore pourrait aider.
Pour des cas d'entrées à peine plus compliquer, l'idiome
classique est de lire ligne par ligne au moyen de getline, puis
d'analyser chaque ligne à part, éventuellement en l'utilisant
d'initialiser un istringstream. Du coup, on a une
synchronisation par ligne automatique.

--
James Kanze GABI Software
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
kanze
Alexandre wrote:
Voici mon probleme:
si j'entre des lettres à la place des chiffres ça boucle sans
fin.


Comment reinitialiser cin ?
(j'ai essayé un clear() mais sans succes).


de mémoire : cin.sync()


Dont le comportement dépend de l'implémentation. Je m'attendrais
dans la plupart des cas un no-op sur un flux d'entrée connecté à
un fichier. (Et Windows et Unix considère que le clavier est un
fichier.)

--
James Kanze GABI Software
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
Ultimataupe
if (!cin.good())
{
cin.clear();
cin.sync();
}

ceci semble fonctionner .

Merci.
Avatar
kanze
Ultimataupe wrote:
if (!cin.good())
{
cin.clear();
cin.sync();
}

ceci semble fonctionner .


Peut-être sur certaines implémentations. Ou peut-être seulement
avec certaines sources de données. (Je n'ai pas de mal à
imaginer une implémentation où il fonctionne avec les entrées du
clavier, mais non si cin est rédirigé pour lire d'un fichier.)

Comme j'ai dit ailleurs, le comportement de cin.sync() est
laissé à la liberté de l'implémentation. J'en connais
effectivement où elle se positionne au début de la ligne, mais
seulement pour les entrées clavier. Ce n'est pas le genre de
choses sur lesquelles on peut compter. (Ton utilisation de
cin.good() n'est pas vraiment correcte non plus, mais je ne
crois pas qu'elle fasse une différence ici.)

La seule façon correcte à traiter le problème, c'est :

if ( ! cin ) {
cin.clear() ;
cin.ignore( INT_MAX, 'n' ) ;
}

Au moins qu'on utilise la solution classique, et lit au moyen de
getline.

--
James Kanze GABI Software
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