IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

Variable pouvant être un double et un string


Sujet :

C++

  1. #1
    Membre éclairé Avatar de nekcorp
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2006
    Messages
    592
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Décembre 2006
    Messages : 592
    Par défaut Variable pouvant être un double et un string
    Bonjour,

    soyez indulgent je débute en C++ et je suis entrain de m'exercer.

    Alors mon exo consiste à demander à l'utilisateur de rentrer ses notes que j'ajoute à un tableau dynamique pour ensuite calculer la moyenne.

    L'utilisateur continue de rentrer ses notes tant qu'il ne tape pas le mot fin

    Voici mon code pour l'instant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
     
     
        vector <double> listeDesNotes;  // On definit un tableau dynamique (vector) vide.
        double moy(0);
        double answer(0);
     
     
        while(answer!="fin"){
            std::cout << "Veuillez entrer vos notes :"<<std::endl;
            cin >> answer;
     
            if(answer=="fin"){
                 break;
            }
            else {
                listeDesNotes.push_back(answer);
            }
        }
     
        // Calcul de la moyenne
    Mon soucis c'est comment définir answer car je ne peux pas lui dire d'être à la fois un double et un string.

    Merci d'avance pour votre aide.

  2. #2
    Membre confirmé
    Homme Profil pro
    .
    Inscrit en
    Octobre 2019
    Messages
    21
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Autre

    Informations professionnelles :
    Activité : .

    Informations forums :
    Inscription : Octobre 2019
    Messages : 21
    Par défaut
    Stocke les données en tant que std::string et utilise std::stod après.

    Quelques astuces :

    • std::cin et std::cout sont liés, donc std::endl est redondant avant de lire de std::cin. '\n' suffit. Pour la différence entre \n et std::endl, lis cela.
    • Je recommande de ne pas utiliser double moy(0) mais double moy = 0 ou double moy{0} à la place. Plus d'information disponible ici sur ce sujet.

  3. #3
    Membre éclairé Avatar de nekcorp
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2006
    Messages
    592
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Décembre 2006
    Messages : 592
    Par défaut
    Merci pour ta réponse, j'ai réglé mon problème.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
     
       vector <double> listeDesNotes;  // On definit un tableau dynamique (vector) vide.
        double moy(0);
        std::string answer;
     
     
        while(answer!="fin"){
            std::cout << "Veuillez entrer vos notes (tapez fin pour arreter la saisie) :";
            std::cin >> answer;
     
            if(answer=="fin"){
                break;
            }
     
            else {
                listeDesNotes.push_back(std::stod (answer));
            }
        }
     
        // Calcul de la moyenne
     
        moy = calculMoy(listeDesNotes);
     
        std::cout<<"Vous avez obtenu une moyenne de : /20" << moy << std::endl;

  4. #4
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Salut,

    En fait, tu dois faire la distinction entre l'introduction (par l'élève) de ses notes et la manière dont tu veux les maintenir en mémoire, afin de pouvoir les utiliser

    Il est, sans doute, "de bon ton" de traiter à la base toutes les entrées effectuées par l'utilisateur comme s'il s'agissait de string, parce que leur valeur peut représenter à peu près tout et n'importe quoi.

    Mais, d'un autre coté, il serait totalement aberrant d'accepter de la part de l'utilisateur qu'il introduise "quelque chose" qui ne pourrait pas être considéré comme (mettons la chaine de caractères "hello world!") une note lorsqu'on s'attend spécifiquement à ce qu'il introduise une note.

    De même, il serait totalement aberrant de maintenir en mémoire "quelque chose" que l'on considère explicitement comme une note sous une forme autre que celle d'une donnée d'un type différent que celui qui nous permet -- effectivement -- de manipuler la note; surtout si ce "quelque chose" ne peut pas être considéré comme une note valide.

    Tu dois donc travailler sans doute en deux temps, à savoir:
    1. accepter que l'utilisateur introduise n'importe quoi dans un premier temps puis
    2. tenter de convertir ce "n'importe quoi" en une note valide et, en fonction du réslutat de cette tentative:
      • si la conversion réussi: c'est très bien, tu peux stocker la note (sous la forme d'un type adapté aux manipulations que tu en feras) en mémoire ou
      • si la conversion échoue: engueuler l'utilisateur pour le rappeler à l'ordre, et recommencer en (1)

    Et ce n'est qu'une fois que cette logique (pas très compliquée, somme toutes) sera mise en place que tu pourra envisager de créer une boucle pour permettre l'extraction de plusieurs notes d'affilées

    La première étape peut être simple, car il peut suffire d'une fonction (tiens, profitons en pour faire en sorte qu'elle puisse fonctionner pour lire des fichiers, tant qu'on y est) qui prendrait la forme de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    std::string readInput(std::istream & ifs){
        std::string input;
        std::getline(ifs, input);
        return input;
    }
    C'est "tout ce qu'il y a de plus simple, n'est-ce pas

    Ensuite, nous voudrons sans doute afficher un message à l'utilisateur pour lui dire ce que l'on attend de sa part. Cependant, ce message n'aura aucun sens si la donnée doit être récupérée depuis un fichier.

    Nous pourrions donc créer une fonction qui provoque effectivement l'affichage si le message à afficher existe, et qui renvoie le résultat de readInput sous une forme proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    std::string maybeAskInput(std::istream & ifs, std::string const & message){
        if(!message.empty())
            std::cout<< message;
        return readInput(ifs);
    }
    Grâce à cela, nous pouvons créer une fonction qui s'occupe spécifiquement de convertir une chaine de caractères en note et qui, selon le cas, pourra afficher un message pour engueuler l'utilisateur ou lancer une exception et qui prendrait une forme proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    bool convertToNote(std::string const & value, double & result, bool showError ){
        size_t pos{0}; // la position finale après conversion
        double temp = std::stod(value, & pos);
        /* est-ce que toute la chaine de caractères a été traitée? */
        if(pos== value.size()){ // si oui, on renvoie la valeur récupérée
            result = temp;
            return true;
        }
        /* si on arrive ici, c'est "qu'un problème" est survenu ... */
        // Soit l'utilisateur n'a pas introduit une valeur entière, et on doit donc l'engueuler */
       if(showError){
           std::cout<<"Veuillez introduire une valeur réelle uniquement \n";
        }else{
            /* soit la donnée vient d'ailleurs, et on lance une exception */
            throw std::runtime_error("incompatible data retrieved");
        }
        /* pour le cas où on n'a pas lancé d'exception */
        return false;
    }
    Maintenant que nous avons tout cela, nous pouvons envisager de créer une boucle pour faire bonne mesure. La fonctions que je te propose de créer va, encore une fois, permettre l'extraction de données depuis un fichier ou depuis l'introduction de l'utilisateur grâce à un simple booléen, et prendra une forme proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    std::vector<double> readNotes(std::istream & ifs, bool showMessage ){
        std::vector<double> notes;
        bool again{true}; // pour savoir s'il faut continuer ou pas
        /* la boucle devra s'effectuer au moins une fois */
        do{
            /* Le message "de base", qui ne demande rien */
            std::string message{""};
            /* si on veut un affichage, le message sera plus complet */
            if(showMessage){
                message.append("Veuillez introduire la note ")
                       .append(std::to_string(notes.size()+1))
                       .append(" (ou \"fin\" pour terminer ");
            }
            auto result = maybeAskInput(ifs, message);
            /* traitons d'office la possibilité que l'on ait obtenu le mot "fin" */
            if(result =="fin"){ 
                again = false;
            }else{ // sinon, on tente la conversion
                double final;
                if(convertToNote(result, note, !message.empty())){
                    /* si la conversion réussi, on peut ajouter la note aux 
                     * tableau de résultats
                     */
                    notes.push_back(final;
                }
            }
        }while(again);
        /* quand on arrive ici, c'est qu'il est temps de renvoyer les notes
         * obtenues
         */
        return notes;
    }
    Maintenant, il ne reste plus qu'à fournir la fonction "main" pour mettre tout cela en musique. Si l'on veut que ce soit l'utilisateur qui introduise ses notes, cela pourrait prendre une forme proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    int main(){
        auto result = readNotes(std::cin, true);
        std::cout<<"Vous avez introduit les "<<result.size() <<" notes que voici :\n";
        for(auto it : result)
            std::cout<<it<<"\n";
        return 0;
    }
    Si on veut extraire les notes d'un fichier (mettons qu'on l'ait appelé data.txt), la fonction main pourrait prendre la forme de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    int main(){
        std::ifstream ifs("data.txt");
        auto result = readNotes(ifs, false);
        std::cout<<"Le fichier contenait les "<<result.size() <<" notes que voici :\n";
        for(auto it : result)
            std::cout<<it<<"\n";
        return 0;   
    }
    Et, pour que cet exemple puisse fonctionner, voici un exemple pour le fichier data.txt:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    12
    15
    13.5
    5.5
    10.7
    19
    fin
    Au final, le principal enseignement que tu dois tirer de tout cela, c'est que n'importe quel problème, aussi complexe soit-il, peut être décomposé en une suite logique d'étapes plus simples à mettre en oeuvre, et que chacune de ces étapes mérite d'être implémentée sous la forme d'une fonction qui ne s'occupe que de l'étape considérée

    Alors, bien sur, j'ai abordé une approche "bottom up" ici, en commençant par les étapes les plus simples, avant de m'attaquer aux étapes les plus complexes.

    Ce qu'il y a sans doute intérêt à faire, c'est de partir d'une approche "top down" pour dresser la liste des différentes étapes qui seront nécessaire pour résoudre le problème le plus compexe, avant d'utiliser une approche "bottom up" pour implémenter ces étapes
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [VB6]Variable pouvant aller jusqu'à 10^77. Possible?
    Par méphistopheles dans le forum VB 6 et antérieur
    Réponses: 11
    Dernier message: 05/03/2015, 08h29
  2. Réponses: 5
    Dernier message: 09/04/2013, 12h27
  3. Réponses: 9
    Dernier message: 31/07/2006, 21h19
  4. [XSD]noeud pouvant être de plusieurs types
    Par jesus144 dans le forum Valider
    Réponses: 2
    Dernier message: 12/04/2006, 14h03
  5. [ImageMagick] Image ne pouvant être affichée car elle contient des erreurs
    Par hutchuck dans le forum Bibliothèques et frameworks
    Réponses: 5
    Dernier message: 09/12/2005, 13h59

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo