[T.P] Gérer les erreurs d'entrée — Partie I

a marqué ce sujet comme résolu.

Bonjour la fonction std::cin » age dans le if chez moi demande deux fois à l’utilisateur d’entrer l’age, (nombre dans le cas du code présent.)

unsigned int nombre {0};
    std::string nom {""};

    std::cout <<"Veuillez entrer un nombre : ";
    std::cin >> nombre;

    if (std::cin >> nombre) //protection contre la mauvaise insertion d'entier par exemle si on entre du texte à la place d'un entier.
    {
        std::cout <<"Voici votre votre age : " << nombre << std::endl;
    }
    else
    {
        std::cout <<"Vous avez entrer une chaine de caractere au lieu de chiffre"<<std::endl;
        std::cin.clear();
        std::cin.ignore(255,'\n');
    }

Pourquoi est-ce que la fonction dans le if me remande deux fois d’introduire un nombre alors que cela devrais simplement faire le renvois de true ou false comme vous l’avez expliqué sur le tutoriel ?

Je vous remercie d’avance à bientôt.

+0 -0

Bonjour,

la fonction std::cin » age dans le if chez moi demande deux fois à l’utilisateur d’entrer l’age,

Tu as 2 fois dans ton code std::cin >> nombre (lignes 5 et 7). C’est donc normal que tu doives entrer deux nombres.

+4 -0

Tu as 2 fois dans ton code std::cin >> nombre (lignes 5 et 7). C’est donc normal que tu doives entrer deux nombres.

Gabbro

Bonsoir Gabbro effet je ne savais pas qu’il fallait la mettre qu’une seule fois dans le if merci pour cette éclaircissement, bonne soirée à vous.

+0 -0

Faute de pouvoir vérifier facilement notre entier, on peut se débarasser du reste de la ligne avec cin.ignore()

#include <iostream>
int main(void) {
    unsigned int nombre;
    for(int i {0}; i < 6; i++) {
        std::cout << "Nombre ? ";
        std::cin >> nombre;
        std::cin.ignore(255, '\n');
        std::cout << "Le nombre vaut " << nombre << std::endl;
    }
}

Ou encore mieux:

#include <iostream>
#include <string>
#include <algorithm>
int main(void) {
    std::string ligne;
    unsigned int nombre;
    bool erreur = false;
    do {
        if(erreur)   std::cout << "Erreur, nombre invalide" << std::endl;
        std::cout << "Nombre ? ";
        std::cin >> ligne;
        erreur = std::find_if(ligne.begin(), ligne.end(), [](char &c){return  ! std::isdigit(c);}) != ligne.end();
    } while(erreur);
    nombre = std::stoi(ligne);
    std::cout << "Le nombre vaut " << nombre << std::endl;
}
+0 -0

Le ignore, c’est vraiment un truc de nettoyage pour virer le bruit lors des erreurs de saisie.

Avec une utilisation systématique, cela va pourrir la lecture de depuis des flux/pipes: echo 1 2 3 4 5 6 | ./mon_executable, chose qui est très, mais vraiment très pratique pour tester rapidement des comportements.

Je trouve ça bien mieux de ne pas supposer qu’il faille obligatoirement un CR entre 2 saisies: des espaces, c’est bien aussi pour des petits trucs comme ici (!= formats de texte bien précis tels que csv/tsv, etc)

(bon après… les flux, c’est vraiment pourri pour valider les saisies à la main)

(bon après… les flux, c’est vraiment pourri pour valider les saisies à la main)

As-tu des suggestions? Est-ce que mon deuxième code est déjà un peu mieux?

On peut utiliser std::find_if pour séparer les champs d’une ligne et les tester adéquatement.

+0 -0

Honnêtement? Ce que je suggère, c’est ce que j’ai mis dans la FAQ C++ de dvpz. Toute lecture se teste et en cas d’échec de lecture, et si le flux n’est pas fermé, alors clear+ignore.

C’est une bonne première approximation qui utilise les flux. Si on veut plus, il faut écrire des machines à états. C’est vite overkill pour des codes pour débutants (comme je le soupçonne ici).

Sinon, j’ai souvenir d’un truc dans le standard qui décode ce qu’il est capable de décoder, et renvoie un pointeur vers le premier truc qui ne matche pas. Ah oui. std::from_chars. Mais… bouaif. Pas pour du code d’exercice.

Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte