Annonce

Réduire
Aucune annonce.

C++ - cours n°5 -> La gestion d'erreur

Réduire
Ceci est une discussion importante.
X
X
  • Filtre
  • Heure
  • Afficher
Tout nettoyer
nouveaux messages

  • C++ - cours n°5 -> La gestion d'erreur

    La gestion des erreurs


    Problématique

    Si nous reprenons une des problématiques précédentes concernant l'enregistrement des notes, on peut facilement imaginer les erreurs rencontrées par l'utilisateur
    • Envoyer une note négative
    • Envoyer une note supérieure à 20
    • Envoyer un caractère à la place d'un nombre réel
    • Ne rien envoyer (appui simplement sur Entrée)


    L'objectif est de contrôler tout cela avec la syntaxe C++... tout en calculant la moyenne des notes enregistrées.

    Pré-Requis

    Tous les cours précédents !

    Enregistrement des données

    Commençons par l'enregistrement des données, il est clair qu'on ne va pas s'amuser à compter le nombre de notes à entrer, pour deux raisons:
    1. C'est pénible (perte de temps)
    2. C'est risqué (risque de ne pas avoir compté le nombre correct de notes à enregistrer)


    On va donc créer une boucle infinie, qui demandera continuellement d'enregistrer une note.

    Euh, oui mais, quand j'ai plus de note, comment on fait pour quitter cette boucle infinie ?

    Simple, on va prévenir l'utilisateur d'un signe qui permettra de breaker (d'interrompre) cette boucle.

    Dans ma problématique, plusieurs choix s'offrent à moi pour interrompre cette boucle,
    • Je n'envoie rien !
    • J'envoie un nombre réel non conforme (négatif, supérieur à 20)
    • J'envoie autre chose qu'un nombre


    Ok, pour l'instant ça va, je comprend bien la problématique, parlons C++ maintenant,

    Pour créer notre boucle infinie, c'est une syntaxe assez simple

    Code:
    while (1){
    
        // suite de mon code
    
    }
    ou ma préférence,

    Code:
    while (true){
    
        // suite de mon code
    
    }
    Ok, et comment interrompre cette boucle alors ?

    Réponse, à l'aide du mot clé break !

    Code:
    while (true){
    
        // suite de mon code
    
        if (condition){
            break; // interruption de ma boucle infinie
        }
    
    }
    Eh oui vous l'aurez compris, lorsqu'on ne connaît pas le nombre de notes à entrer, nous allons utiliser la boucle while, par contre si on connaît ce nombre, on utilisera la boucle for.

    Ok, je vois pour ma boucle infinie, je comprend pourquoi l'utiliser, mais j'enregistre ça dans quel objet ?

    Bonne question, mais vous l'aurez deviné, on a vu l'objet vector dans notre cours précédent, alors allons-y avec cet objet

    Demande utilisateur

    Il faut parler maintenant du type où nous allons recevoir la note.

    Vous allez me dire, c'est simple ! On prend le type double

    Eh bien non ! Comment faîtes vous si l'utilisateur n'entre aucune note ?
    En effet cin a des effets de bord, c'est à dire que des choses imprévues peuvent se passer si la donnée attendue n'est pas conforme, il faut donc analyser (parser) la chaîne de caractères, avant d'exécuter quoi que se soit.

    On utilisera donc le type string, et on pourra vérifier si c'est une chaîne vide

    Code:
    string line;
    
    getline(cin, line); // On demande à l'utilisateur une chaîne de caractères
    
    if (line.empty()){
        // Afficher moyenne
        // interruption de la boucle
    }
    Par contre, il faut que je passe d'une chaîne de caractères à un nombre flottant compris entre 0 et 20 et pour cela nous allons utiliser la fonction stod.

    Pour l'utiliser vous aurez besoin de compiler en C++11 (norme) et charger la librairie string, donc ne pas oublier

    Code:
    #include <string>
    La fonction s'utilise de cette manière,

    Code:
    note = stod(line);
    Pas compliqué me direz-vous, mais en fait c'est pas si simple,

    Si vous entrez une chaîne, par exemple "bonjour", comment va réagir cette fonction ? Très mal, je vous le dis, on va donc essayer et au cas où, faire en sorte de...

    Pour notre problématique, je pense résoudre de la sorte,

    Si j'ai quelque chose de non conforme, je calcule ma moyenne des notes avec toutes celles enregistrées sauf la valeur non conforme évidemment et je quitte la boucle.

    Pour essayer la transformation string -> double, avec la fonction stod, on utilisera une gestion d'erreur avec la syntaxe try - catch

    Elle fonctionne comme cela

    Code:
    try{
    
        // Utilisation de stod
    
    }
    
    catch (const invalid_argument & ia){
    
        // Affichage de la moyenne
        // On interrompt la boucle
    
    }
    Dans cette partie de code, on pourrait insérer la condition où la note ne serait pas comprise entre 0 et 20.

    Attention pour invalid_argument, il faut charger la librairie stdexcept.

    Code:
    #include <stdexcept>
    Affichage de la moyenne

    Pour afficher la moyenne, on va créer une fonction prenant en argument l'objet vector et ne renvoyant rien.

    Code:
    void displayMean(vector<double> notes)
    Deux solutions possibles,

    Soit le tableau de notes est vide, dans ce cas on affiche "Pas de notes enregistrées".
    Soit le tableau de notes n'est pas vide, dans ce cas on calcule la moyenne et on l'affiche, "La moyenne est de ".

    Pour vérifier si le tableau est vide, on peut vérifier que sa taille est nulle.

    Code:
    if (notes.size() == 0){
    
        // "Pas de notes enregistrées"
    
    }
    Pour résoudre la problématique et pour afficher les résultats vous avez tout ce qu'il faut, à vous de jouer

    Le code final à compléter pour vous guider au cas où,

    Code:
    #include <iostream>
    #include <vector>
    #include <string>
    #include <stdexcept>
    
    using namespace std;
    
    void displayMean(vector<double> notes);
    
    int main()
    {
        // déclaration de variables
    
        while (true){
    
            // demande utilisateur avec getline
    
            // Si l'utilisateur entre rien ?
    
            try{
                // Essai conversion string -> double
            }
    
            catch (const invalid_argument & ia){
                // Essai n'est pas concluant, on fait quoi ?
            }
    
            // Ajout de la note dans le tableau
        }
    
        return 0;
    }
    
    void displayMean(vector<double> notes){
    
        // vos variables
    
        // Si notes est vide ?
    
        // Sinon calculer moyenne et l'afficher
    
    }
    Bon courage !
Chargement...
X