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 :

petit probleme à l'exécution


Sujet :

C++

  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    116
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Avril 2008
    Messages : 116
    Par défaut petit probleme à l'exécution
    Bonjour je suis entrain de faire 1 pb basique de c++, il s'agit de construire une classe qui permet d'ajouter des integer. Si l'ensemble est plein , ou si l'element que l'on veut inserer y est deja => message pour le signaler. Il faut en plus du constructeur par defaut, un constructeur avec comme parametre la taille du tableau et une fonction pour avoir le cardinal de l'ensemble.
    Voila ce que j'ai fait à la compliation ça va mais à l'execution ça "bugge" merci de vôtre aide
    Coold

    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
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
     fichier.h
    #pragma once
     
    //-----------------
    #define NON 0
    #define OUI 1
    #define EXISTE_OK 2
    #define NO_EXISTE 3
    #define OK_AD 4
    #define AD_EXISTE 5
    #define ENS_FULL 6
    //-----------------
     
    class CSetInteger
    {
    public:
        // constructeur par défaut de la classe
        CSetInteger(void);
     
        //constructeur pour initialiser le tableau
        CSetInteger(int dTaille);
     
        //destructeur de la classe
        ~CSetInteger(void);
     
    private:
        // taille du tableau
        int m_dTaille;
        //pointeur du tableau
        int * m_dTab;//????????????
        // position courante
        int m_dCurPos;
    public:
        // fonction pour verifier si l'element existe ou pas
        void Existe(int dNbr, int * pEx_RC);
        // fonction d'ajout d'un nouvel element
        void IntegerAdd(int dNbr, int * pAd_RC);
        // fonction permettant d'avoir le nombre d'éléments de l'objet
        int CardinalEnsemble(void);
     
        // fonction d'affichage de l'ensemble
        void Affiche(void);
    };
     
     
    fichier.cpp
    #include "SetInteger.h"
    #include<stdio.h>
    #include<malloc.h>
    #include<string.h>
    #include<assert.h>
     
     
    // constructeur par defaut de la classe 
    CSetInteger::CSetInteger(void)
    : m_dTaille(0)
    , m_dCurPos(0)
    {
    }
     
    //destructeur de la classe
    CSetInteger::~CSetInteger(void)
    {
        free (m_dTab);
    }
     
    //constructeur d'initialisation de l'objet
    CSetInteger::CSetInteger(int dTaille)
    {
        m_dTaille = dTaille;
        m_dTab = (int *)malloc(sizeof(int) * m_dTaille);
        if(m_dTab == NULL)
        {
            printf("Erreur allocation mémoire pour l'objet\n");
            assert(0);
        }
    }
     
    // fonction pour verifier si l'element existe ou pas
    void CSetInteger::Existe(int dNbr, int * pEx_RC)
    {
        int dExiste, dTrouve;
     
        *pEx_RC = NO_EXISTE;
        //dExiste = NON;
        dTrouve = NON;
        while(dTrouve == NON && m_dCurPos != m_dTaille)
        {
            if(m_dTab[m_dCurPos] == dNbr)
            {
                //dExiste = OUI;
                dTrouve = OUI;
                *pEx_RC = EXISTE_OK;
            }
            else
            {
                dTrouve = NON;            
                m_dCurPos++;
            }
        }
        if (*pEx_RC = EXISTE_OK);
            return;
    }
     
    // fonction d'ajout d'un nouvel element
    void CSetInteger::IntegerAdd(int dNbr, int * pAd_RC)
    {
        *pAd_RC = OK_AD;
     
        //---------------------------------------------
        //Tant que l'on est dans l'ensemble
        // si le nombr est + grand on passe au suivant
        //sinon on l'insere à la position courantes
        //---------------------------------------------
        while(m_dCurPos != m_dTaille)
        {
            if(dNbr > m_dTab[m_dCurPos])
                m_dCurPos++;
            else
                m_dTab[m_dCurPos] = dNbr;
     
            return;
        }
     
        //-----------------------------------------
        //traitement du cas ou l'ensemble est plein
        //-----------------------------------------
        if(m_dCurPos > m_dTaille)
        {
            *pAd_RC = ENS_FULL;
            return;
        }
    }
     
    // fonction permettant d'avoir le cardinal de l'ensemble
    int CSetInteger::CardinalEnsemble(void)
    {
        int dI;
     
        dI = 0;
        while(dI != m_dCurPos)
            dI++;
        return dI;
    }
     
     
    // fonction d'affichage de l'ensemble
    void CSetInteger::Affiche(void)
    {
        for(int dI = 0; dI < m_dCurPos; dI++)
            printf("%d", m_dTab[m_dCurPos]);
    }
     
     
    main.cpp
    #include "SetInteger.h"
    #include<stdio.h>
    #include<stdlib.h>
    int main()
    {
        CSetInteger oEnsemble(10);//declaration et init objet de taille 10
        int dNbr, dEx_RC, dAd_RC;
        char cRep;
     
        printf("PROGRAMME D'AJOUT D'ENTIERS\n");
     
        printf("Voulez-vous introduire un entier ? (o,n)");
        cRep = getchar();
        fflush(stdin);
        while (cRep != 'n')
        {
            printf("Entrez l'entier que vous desirez inserer : ");
            scanf("%d", &dNbr);
     
            //------------------------------------------------------------------
            //appel à la fonction qui teste si l'element appartient à l'ensemble
            //s'il n'appartient pas 
            //    alors on l'ajoute et gestion des erreurs
            //------------------------------------------------------------------
     
            oEnsemble.Existe(dNbr, &dEx_RC);
     
            if(dEx_RC == EXISTE_OK)
            {
                exit(0);
            }
            else 
            {
                oEnsemble.IntegerAdd(dNbr, &dAd_RC);
     
                if(dAd_RC == EXISTE_OK)
                {
                    printf("l'element existe deja et ne peut etre insere\n");
                    exit(0);
                }
                if(dAd_RC == ENS_FULL)
                {
                    printf("l'enemble est plein et l'element ne peut etre insere \n");
                    exit(0);
                }
            }
            printf("L'insetion s'est bien deroulee\n");
            printf("Voulez-vous introduire un entier ? (o,n) ");
            cRep = getchar();
            fflush(stdin);
        }
     
        //-----------------------
        //affichage de l'ensemble
        //-----------------------
        oEnsemble.Affiche();
     
    }

    ====

  2. #2
    Membre éprouvé
    Inscrit en
    Avril 2008
    Messages
    155
    Détails du profil
    Informations forums :
    Inscription : Avril 2008
    Messages : 155
    Par défaut
    "ça "bugge" merci de vôtre aide"

    c'est un peu flou!

    qu'est ce qui ne marche pas? t'as un message d'erreur?ya une fonction qui marche pas?

    quand c'est un pti bout de code a tester ca va mais la c'est un peu long, et puis c'est l'heure d'aller manger

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    116
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Avril 2008
    Messages : 116
    Par défaut
    en fait quand je veux introduire 1 int , il se plante et j'ai Un fenetre qui me propose de debugger mais je ne m'y connais pas ...

  4. #4
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Par défaut
    J'ai juste survolé le code, donc je ne garanti rien sur le résultat :

    - La position courante est gérée comme une variable membre, mais n'est pas remise à 0. Ca peut encore marcher pour le premier ajout, mais pas le second
    - D'ailleurs, pourquoi en faire une variable membre ? Qu'est-ce que ça apporte
    - Tu n'augmentes pas la taille quand tu ajoutes une donnée
    - D'ailleurs, tu n'ajoute pas de donnée, tu ne fais qu'en remplacer une existante par la nouvelle
    - Tu utilises des entiers et des #define pour gérer des informations d'état (ok,...). Utiliser des enums (ou des booléens, quand les valeurs sont OUI et NON) serait plus clair et éviterait des erreurs
    - Ta fonction d'ajout devrait retourner l'information de succès ou pas, plutôt que de prendre cette information en argument variable (et si on voulait garder ça, un passage par référence serait préférable à un passage par pointeur).
    - Tes algorithmes sont sous-optimaux (ex : O(n) pour l'ajout, là où on peut avoir O(ln n), voire O(1) si on limite l'ensemble des données ajoutables). Mais bon, il s'agit probablement d'un exercice scolaire, et avoir les bons algos demanderait plus de code.
    - J'ai vu un if(a=b) qui devrait être if(a==b)
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 635
    Par défaut
    Salut, et bienvenue sur le forum.

    Déjà, on ne le répète jamais assez, mais, quand on code en C++, il est fortement préférable d'utiliser les classes du C++ plutot que les fonctions héritées du C.

    Je vais "glisser" sur la classe vector, étant donné que ton exercice consiste à fournir une classe qui lui ressemble, mais je t'invite donc à éviter les fonctions printf, getc et autres au profit des flux d'entrée/sortie standard, respectivement cin et cout, tous les deux disponibles dans l'espace de noms std par inclusion du fichier d'en-tête <iostream>.

    De la même manière, je te conseillerais fortement de préférer le système d'allocation dynamique fournit par le C++ sous la forme de new (new[]) et delete (delete[]) aux fonctions *alloc et free

    En outre, il faut savoir que le prototype de la fonction principale main est
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    int main()
    /* ou */
    int main( int argc, char *argv[])
    Si ton compilateur était bien réglé, il devrait t'indiquer un avertissement (au minimum) t'indiquant que la fonction ne renvoie rien.

    La raison en est que la valeur renvoyée par cette fonction permet au système d'exploitation de savoir la manière dont le programme s'est terminé: selon le système d'exploitation, il existe deux ou trois valeurs
    • EXIT_SUCCES : qui est une macro équivalant à 0 et signalant que le programme s'est bien terminé
    • EXIT_FAILURE : qui est une macro équivalant à 1 et signalant que le programme s'est terminé sur une erreur
    • (pour certains systèmes d'exploitation) EXIT_WARNING : qui est une macro équivalant à 2 et signalant que le programme s'est terminé sur un avertissement (une erreur "non fatale" )
    et dont le but est de permettre l'écriture de script sous une forme proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    programe1 && programe2 &2 &1 programme3
    qui demande, en gros, de lancer programme1, puis, s'il s'est correctement terminé de lancer programme2 et sinon (s'il s'est terminé sur une erreur ou sur un avertissement), de lancer programme3

    Enfin, ce n'est pas parce que, pour une raison ou une autre l'utilisateur a fait une c en essayant d'introduire plus d'entiers que ce qu'il ne pouvait que tu ne dois pas donner la permission de voir quand même le contenu de ton objet (tu pourrais d'ailleurs même prévoir, pourquoi pas , la possibilité d'obtenir les informations dans la boucle d'encodage, de manière à ce que l'utilisateur puisse vérifier ce qu'il a fait

    Et, cerise sur le gâteau, tant qu'à faire, ce serait pas mal de ne pas oublier que l'utilisateur est, par défaut, un imbécile distrait, et donc de t'assurer en permanence que ce qu'il introduit correspond à ce que l'application attend de lui

    Accessoirement (enfin, pas si accessoirement que cela), on pourrait faire valoir que:
    • il existe un type booléen, qui vaut true ou false : le type bool, qu'il est intéressant d'utiliser
    • il est souvent préférable d'utiliser une valeur de retour plutôt qu'un argument, si du moins, tout ce que tu veux, c'est savoir si une méthode de ta classe a correctement fait son travail (le type bool prend alors tout son sens )
    • il faut se méfier des directive pragma... ce n'est pas portable, il vaut mieux utiliser des "guard dogs"
    • il n'est pas nécessaire de préciser le type void dans la liste d'arguments, si une fonction n'en demande pas
    • il est généralement conseillé d'éviter les #define quand il s'agit d'avoir des valeur d'état... les énumérations sont parfaites pour cet usage

    Maintenant que je t'ai bien assommé avec toutes les remarques que m'inspiraient la lecture en diagonale de ton code, voyons un peu comment les prendre en compte...

    Nous allons commencer par virer les fonctions issues du C en les remplaçant par les équivalents C++, et nous assurer que le programme renvoie une valeur cohérente quand tout se passe bien, et en prenant en compte les remarques "subsidiaires" qui peuvent l'être (sans modifier la logique que tu as utilisé... on en parlera plus tard ).

    Voici à peu près la forme qu'il prendrait
    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
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    /* je préfère honnetement les "guard dogs"
    #pragma once
     */
    #ifndef SETINTEGER_H
    #define SETINTEGER_H 
    //-----------------
    /* ces deux-ci sont inutiles, on a les booléens :D
    #define NON 0
    #define OUI 1
    */
    /* comme j'ai décidé de ne pas modifier ta logique, on les garde pour l'instant
     * mais on verra plus tard qu'ils sont également inutiles :D
     */
    #define EXISTE_OK 2
    #define NO_EXISTE 3
    #define OK_AD 4
    #define AD_EXISTE 5
    #define ENS_FULL 6
    //-----------------
     
    class CSetInteger
    {
    public:
        // constructeur par défaut de la classe
        CSetInteger();
     
        //constructeur pour initialiser le tableau
        CSetInteger(int dTaille);
     
        //destructeur de la classe
        ~CSetInteger();
     
    private:
        // taille du tableau
        int m_dTaille;
        //pointeur du tableau
        int * m_dTab;// si, il le faut... c'est la responsabilité majeure de ta classe :D
        // position courante
        int m_dCurPos;
    public:
        // fonction pour verifier si l'element existe ou pas
        void Existe(int dNbr, int * pEx_RC);
        // fonction d'ajout d'un nouvel element
        void IntegerAdd(int dNbr, int * pAd_RC);
        // fonction permettant d'avoir le nombre d'éléments de l'objet
        int CardinalEnsemble(void);
     
        // fonction d'affichage de l'ensemble
        void Affiche(void);
    };
    #endif //SETINTEGER_H
    fichier.cpp
    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
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
     
    #include "SetInteger.h" //OK, lui on en a besoin
    /* mais tous ceux-là, il vaut mieux les éviter...
     * Ils seront avantageusement remplacés par <iostream>
     * Seul assert.h pourrait s'avérer intéressant, mais on lui préfèrerait alors <cassert>
     * et encore, on se rend compte que l'on n'en a pas besoin
    #include<stdio.h>
    #include<malloc.h>
    #include<string.h>
    #include<assert.h>
    */
    #include <iostream> 
     
    // constructeur par defaut de la classe 
    CSetInteger::CSetInteger()
    : m_dTaille(0),
    m_dTab(NULL), //tant qu'à faire, initialise le aussi :D
    m_dCurPos(0)
    {
    }
    /* nota: pour rendre l'utilisation du constructeur par défaut cohérente
     * il serait sans doute intéressant de prévoir une méthode permettant
     * de modifier la taille :D
     */
    //destructeur de la classe
    CSetInteger::~CSetInteger()
    {
        delete[] m_dTab; //utilisation de delete (ici delete[] parce que c'est un
                  // tableau au lieu de free
    }
     
    //constructeur d'initialisation de l'objet
    CSetInteger::CSetInteger(int dTaille) //utilise les listes d'initilalisation
                                      //pour tous les membres que tu peux ;)
    m_dTaille(dTaille),
    m_dCurPos(0) 
    {
        /* m_dTaille = dTaille; n'est plus nécessaire: il est dans la liste d'initialisation :D */
        m_dTab = new int[dTaille];//remplacement de malloc par new
        /* Ce code est inutile: new lance une exception de type
         * std::bad_alloc si l'allocation échoue...
         * on pourrait éventuellement envisager de la récupérer dans la fonction
         * qui déclare l'instance de notre classe, mais ici, le risque d'échec de
         * l'allocation dynamique est suffisemment restreint pour que l'on
         * puisse décider de ne pas le faire :D
        if(m_dTab == NULL)
        {
            printf("Erreur allocation mémoire pour l'objet\n");
            assert(0);
        }
        */
    }
     
    // fonction pour verifier si l'element existe ou pas
    void CSetInteger::Existe(int dNbr, int * pEx_RC)
    {
        /*je sais qu'on peut, mais je n'aime pas les déclarations successives 
         * je préfère mettre une déclaration par ligne :D
         */
        bool dExiste; 
        bool dTrouve;
     
        *pEx_RC = NO_EXISTE;
        //dExiste = NON;
        dTrouve = false;
        /* cette boucle, bien que je ne l'ai pas modifiée, cette boucle
         * va te poser problème: tu modifie la valeur de m_dCurPos sans
         * garder la position du dernier élément inséré... (je croyais qu'il servait
         * à ca, ce membre :D)... tu devrais utiliser une variable temporaire ;)
         */
        while(dTrouve == false && m_dCurPos != m_dTaille)
        {
            if(m_dTab[m_dCurPos] == dNbr)
            {
                //dExiste = OUI;
                dTrouve = OUI;
                *pEx_RC = EXISTE_OK;
            }
            else
            {
                dTrouve = NON;            
                m_dCurPos++;
            }
        }
        /* il est généralement mal vu de provoquer un retour de fonction
         * alors qu'elle n'en demande pas... d'autant plus que,une fois que  tu
         * sors de ta boucle, la valeur de pEx_RC est correcte ;)
         * ce code ne sert donc à rien... viré :D
        if (*pEx_RC = EXISTE_OK);
            return;
       */
    }
     
    // fonction d'ajout d'un nouvel element
    void CSetInteger::IntegerAdd(int dNbr, int * pAd_RC)
    {
        *pAd_RC = OK_AD;
     
        //---------------------------------------------
        //Tant que l'on est dans l'ensemble
        // si le nombr est + grand on passe au suivant
        //sinon on l'insere à la position courantes
        //---------------------------------------------
        /*soit, mais que fais tu de l'élément qui se trouvait avant
         * à l'emplacement choisi ???
         */
        while(m_dCurPos != m_dTaille)
        {
            if(dNbr > m_dTab[m_dCurPos])
                m_dCurPos++;
            else
                m_dTab[m_dCurPos] = dNbr;
           /* te rend tu compte que tu quitte d'office la fonction avec
            * ce return, dés que tu arrive en fin de boucle ???
            * ce n'est surement pas ce que tu veux... viré :D
            return;
            */
        }
     
        //-----------------------------------------
        //traitement du cas ou l'ensemble est plein
        //-----------------------------------------
        /* ne trouve tu pas plus logique de faire le test avant d'essayer d'insérer
         * un élément, et meme de n'entrer dans la boucle
         * que s'il y a effectivement la place pour rajouter un élément ??? */
        if(m_dCurPos > m_dTaille)
        {
            *pAd_RC = ENS_FULL;
            return;
        }
    }
     
    // fonction permettant d'avoir le cardinal de l'ensemble
    int CSetInteger::CardinalEnsemble()
    {
        int dI;
     
        dI = 0;
        while(dI != m_dCurPos)
            dI++;
        return dI;
    }
     
     
    // fonction d'affichage de l'ensemble
    void CSetInteger::Affiche()
    {
        for(int dI = 0; dI < m_dCurPos; dI++)
            std::cout<< m_dTab[m_dCurPos]<<" "; //remplacer printf par cout ;)
    }
    main.cpp
    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
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
     
    #include "SetInteger.h"
    /* ici aussi, on remplace avantageusement les deux fichiers par <iostream>
    #include<stdio.h>
    #include<stdlib.h>
    */
    #include <iostream>
    int main()
    {
        CSetInteger oEnsemble(10);//declaration et init objet de taille 10
     
        /*je sais qu'on peut, mais je n'aime pas les déclarations successives 
         * je préfère mettre une déclaration par ligne :D
         */
        int dNbr;
        int dEx_RC; 
        int dAd_RC;
        char cRep;
     
        std::cout<<"PROGRAMME D'AJOUT D'ENTIERS"<<std::endl; //remplacer printf par cout
        /* nota: std::endl a l'énorme avantage de
         *     - passer à la ligne
         *     - forcer la vidange du buffer
         */
     
        std::cout<<"Voulez-vous introduire un entier ? (o,n)"; //idem
        std::cin>>cRep;
        /* supprimé pour l'instant... on en reparle quand on arrive à la sécurisation
         * :D
        fflush(stdin);
        */
        while (cRep != 'n')
        {
            std::cout<<"Entrez l'entier que vous desirez inserer : ";
            cin>>dNbr;// remplacer scanf par cin
     
     
            //------------------------------------------------------------------
            //appel à la fonction qui teste si l'element appartient à l'ensemble
            //s'il n'appartient pas 
            //    alors on l'ajoute et gestion des erreurs
            //------------------------------------------------------------------
     
            oEnsemble.Existe(dNbr, &dEx_RC);
     
            if(dEx_RC == EXISTE_OK)
            {
     
                /*Le fait de ne pas pouvoir ajouter un élément existant
                 *justifie-t-il de quitter l'application si brutalement ?
                 * je ne suis pas de cet avis...*/
                exit(0);
            }
            else 
            {
                oEnsemble.IntegerAdd(dNbr, &dAd_RC);
     
                if(dAd_RC == EXISTE_OK)
                {
                    std::cout<<"l'element existe deja et ne peut etre insere"
                             <<std::endl;
                    /* idem */
                    exit(0);
                   */
                }
                /* par contre, il faut donc s'assurer que le fonctionnement
                 * reste identique
                 */
                if(dAd_RC == ENS_FULL)
                {
                    std::cout<<"l'enemble est plein et l'element ne peut etre insere"
                             <<std::endl;
                   /* idem
                    exit(0);
                    */
                }
            }
            std::cout<<"L'insetion s'est bien deroulee"<<std::endl
                     <<"Voulez-vous introduire un entier ? (o,n) ";
            std::cin>>cRep;
        }
        oEnsemble.Affiche();
        return 0;
    }
    Tu remarquera que j'ai rajouté plein de commentaires dans le code...

    Tous ces commentaires rajoutés ont pour but de te permettre de comprendre ce que j'ai modifié, et pourquoi, mais aussi d'attirer ton attention sur les erreurs de logique que tu as commises.

    A vrai dire, je te soupçonne très fortement (c'est bien plus une constation qu'une attaque personnelle, n'est-ce pas) de t'être "jeté sur ton clavier" et d'avoir commencé à "vomir ton code" sans avoir pensé au préalable à un algorithme cohérent qui t'assure que chaque fonction réagit exactement de la manière à laquelle tu t'y attend.

    Cette erreur est classique chez les gens qui commencent en programmation, aussi, je me permet une petite disgression pour te donner un conseil supplémentaire:
    [MODE DISGRESSION ON]
    Avant de commencer à écrire la première ligne de code, prend l'habitude de répondre à quatre questions de base:
    1. que doit faire mon application
    2. de quelles données mon application a-t-ellle besoin
    3. où mon application va-t-elle obtenir ces données
    4. et la plus importante de toute: quelle est le traitement logique que mon application doit appliquer à ces données

    en sachant qu'il est généralement inutile de vouloir passer à la question suivante tant que tu n'a pas trouvé une réponse correcte à celle à laquelle tu es occupé à répondre.

    Tu trouveras le plus souvent les réponses aux trois premières questions dans l'énoncé, et elles auront comme but principal de te permettre d'éclaircir les choses lorsque tu devra répondre à la dernière.

    Mais cette dernière question représentera, finalement, tout le travail "intéressant" car, il s'agit en fait de prendre une feuille et un crayon et de réfléchir point par point à l'ensemble de la logique qu'il faut suivre, pour chaque fonction, pour que, d'un point de départ donné (l'appel de la fonction), elle finisse à un point d'arrivée donné (le retour de la fonction) en étant sur que son comportement correspond exactement à ce que tu attend d'elle.

    De la même manière, il faut penser au fait qu'une classe doit être seule responsable de son contenu... ainsi, le fait que l'insertion échoue (pour une raison ou une autre) devrait être géré... dans ta classe, et non dans la fonction principale

    J'ai bien conscience qu'en cours, on apprend souvent la conception et l'algorithmique après avoir appris un langage, et j'ai meme conscience du fait que l'algorithmique se limite souvent au flowchart ou, avec un peu de chance, au pseudo code...

    Aussi, je t'invite avec insistance à "prendre un peu d'avance" et à te renseigner sur les différentes méthodes de conception et d'algorithmique qui existent

    A titre preso, la méthode algorithmique qui a ma préférence, est le Nassi-Schneiderman (mais bon, d'aucuns te diront que c'est trop "petits dessins")
    [MODE DISGRESSION OFF]
    Voyons maintenant comment faire quelque chose de cohérent...

    Mais, pour cela, il vaut peut être mieux reprendre tout depuis le début, et donc, commencer par répondre aux quatre questions que j'ai introduites dans ma disgression.

    Que doit faire mon application
    L'application doit:
    • permettre de gérer une classe personnelle
    • demander à l'utilisateur ce qu'il veut faire (parmi les choix "insérer un entier", "afficher le contenu" ou "quitter")


    la classe doit gérer un tableau d'entier

    Ca, c'est ce que tu as dit au départ, mais il est donc intéressant de détailler un peu:
    Elle devra:
    • permettre l'insertion d'un entier, tout en s'assurant de renvoyer une valeur de réussite ou d'échec
    • permettre d'afficher les différents éléments insérés
    • s'occuper de la gestion du tableau dans son ensemble
    • (éventuellement) fournir un message indiquant l'erreur survenue lors de la tentative d'insertion

    Cela nous permet de répondre à la deuxième question:
    De quelles données mon application et ma classe ont-elles besoin
    L'aplication a besoin:
    • d'une instance de la classe
    • d'une variable permettant de connaitre le choix de l'utilisateur


    La classe a besoin:
    • d'un tableau géré dynamiquement capable de contenir des entiers
    • d'un entier représentant le nombre maximal d'élément que le tableau peut contenir
    • d'un entier représentant l'indice du dernier élément inséré
    • d'une chaine de caractères indiquant l'erreur survenue lors de la dernière instruction reçue
    • de la valeur de l'entier à insérer (quand on est en phase d'insertion)

    On peut donc passer à la troisième question:

    Où la classe et l'application vont-elle obtenir ces informations
    • La taille du tableau est obtenue de la fonction appelante lors de la création de l'instance.
    • le nombre d'éléments déjà inséré sera géré en interne
    • le tableau d'entiers sera géré en interne, sur base de la taille fournie lors de la création
    • Le message d'erreur sera géré en interne si une erreur survient (avec des valeurs connues à l'avance, selon l'erreur)
    • la valeur de l'entier à insérer est fournie par l'utilisateur


    Tu l'auras sans doute remarqué, je n'ai fait ici que présenter les mêmes choses sous un autre angle ... mais, au moins, on en arrive à une compréhension correcte de ce qui se passe

    Il est temps maintenant de passer au gros morceau: répondre à la quatrième question:
    Quel traitement logique la classe et l'application doivent-elles fournir
    Pour l'application:

    L'application doit :
    demander à l'utilisateur combien d'élément il souhaite pouvoir mettre dans l'instance de la classe,
    créer l'instance de la classe en conscéquence
    "boucler" sur la proposition des choix jusqu'à ce que l'utilisateur décide de quitter
    Si on demande l'insertion et qu'elle échoue, provoquer l'affichage de l'erreur survenue
    Un dernier affichage sera forcé lorsque l'utilisateur décidera de quitter

    Pour la classe:

    Lors de la création, elle doit:
    allouer dynamiquement un tableau d'entiers capable de contenir le nombre indiqué par l'utilisateur
    initialiser la taille maximale à la valeur du nombre indiqué par l'utilisateur
    initialiser l'indice du dernier élément inséré à 0
    initialiser le message à une chaine vide

    Lors de la destruction, elle doit:
    désallouer le tableau (les autres membres sont détruits automatiquement

    Lors de l'insertion, elle doit:
    • Vérifier s'il est encore possible d'insérer un élément
      si c'est possible
      • Demander la valeur à insérer
      • Vérifier si l'élément existe déjà (il faut une boucle pour vérifier ceci)
        S'il existe:
        • donner la valeur de "l'element existe deja" au message d'erreur
        • renvoyer "false"

        sinon
        • incrémenter l'indice du dernier élément existant
        • insérer le l'élément après le dernier élément existant
        • (éventuellement) afficher que l'insertion s'est correctement déroulée

      sinon
      • donner la valeur de "impossible rajouter un element supplementaire" au message d'erreur
      • renvoyer "false"
    • renvoyer "true", vu que, si on arrive ici, c'est que tout s'est bien passé

    lorsque l'application demande le message d'erreur, elle doit:
    renvoyer simplement le message d'erreur, sous forme constante

    Avec toutes ces informations, et mis à part le fait qu'il manque une boucle, tu devrais presque être en mesure de créer quelque chose d'efficace

    Si tu as des questions, n'hésite pas à les poser, mais j'aime autant te laisser "suer" un peu là dessus (c'est le meilleur service à te rendre )

    PS: tu peux te vanter de m'avoir incité à battre tous les records en terme de taille d'un message
    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

  6. #6
    Rédacteur

    Avatar de ram-0000
    Homme Profil pro
    Consultant en sécurité
    Inscrit en
    Mai 2007
    Messages
    11 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Consultant en sécurité
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2007
    Messages : 11 517
    Par défaut
    Citation Envoyé par koala01 Voir le message
    Beaucoup de choses
    Moi, je dis : joli (et je le pense)
    Raymond
    Vous souhaitez participer à la rubrique Réseaux ? Contactez-moi

    Cafuro Cafuro est un outil SNMP dont le but est d'aider les administrateurs système et réseau à configurer leurs équipements SNMP réseau.
    e-verbe Un logiciel de conjugaison des verbes de la langue française.

    Ma page personnelle sur DVP
    .

  7. #7
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    116
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Avril 2008
    Messages : 116
    Par défaut
    "Le savoir est mieux quand il est partagé", de quelqu'un...
    Merci pour tous vos conseils et critiques bien judicieuses.
    je ne connaisais pas le <stdio> c'est quoi la différence avec le <stdio.h>, je vois qu'il y'a y 1 erreur à la compilation et justement sur la ligne du stio: fatal error C1083: Impossible d'ouvrir le fichier include*: 'stdio'*: No such file or directory.(j'utilise Microsoft Visual Studio 2005),
    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
     
     //constructeur d'initialisation de l'objet
    CSetInteger::CSetInteger(int dTaille) //utilise les listes d'initilalisation
                                      //pour tous les membres que tu peux ;)
    m_dTaille(dTaille),
    m_dCurPos(0) 
    {
        /* m_dTaille = dTaille; n'est plus nécessaire: il est dans la liste d'initialisation :D */
        m_dTab = new int[dTaille];//remplacement de malloc par new
        /* Ce code est inutile: new lance une exception de type
         * std::bad_alloc si l'allocation échoue...
         * on pourrait éventuellement envisager de la récupérer dans la fonction
         * qui déclare l'instance de notre classe, mais ici, le risque d'échec de
         * l'allocation dynamique est suffisemment restreint pour que l'on
         * puisse décider de ne pas le faire :D
        if(m_dTab == NULL)
        {
            printf("Erreur allocation mémoire pour l'objet\n");
            assert(0);
        }
        */
    }
    je suis sûr de ben comprendre, comment se fait la gestion des erreurs

    Merci

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 635
    Par défaut
    Citation Envoyé par coold Voir le message
    "Le savoir est mieux quand il est partagé", de quelqu'un...
    Merci pour tous vos conseils et critiques bien judicieuses.
    je ne connaisais pas le <stdio> c'est quoi la différence avec le <stdio.h>, je vois qu'il y'a y 1 erreur à la compilation et justement sur la ligne du stio: fatal error C1083: Impossible d'ouvrir le fichier include*: 'stdio'*: No such file or directory.(j'utilise Microsoft Visual Studio 2005),
    Je n'ai pas parlé de <stdio>, j'ai parlé de <iostream>

    Les noms des fichiers d'en-tête sont souvent des abréviations:
    • stdio. STandart Input Output (.Header) (en francais: entrées/sorties standard)
    • iostream Input Output STREAM (en français: flux d'entrées/sorties)

    Pour les fichiers fournis par le standard, tu peux estimer que tous les fichiers ayant une extension .h sont des fichiers d'en-têtes fournis par le standard du C et que les fichiers sans extensions sont des fichiers fournis par celui du C++.

    On peut aussi noter que, pour compatibilité uniquement, le C++ fournis des adaptations de fichiers d'en-tête fournis par le standard C.

    Les noms de fichiers sont alors préfixés par la lettre C (cstdio , ...)
    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
     
     //constructeur d'initialisation de l'objet
    CSetInteger::CSetInteger(int dTaille) //utilise les listes d'initilalisation
                                      //pour tous les membres que tu peux ;)
    m_dTaille(dTaille),
    m_dCurPos(0) 
    {
        /* m_dTaille = dTaille; n'est plus nécessaire: il est dans la liste d'initialisation :D */
        m_dTab = new int[dTaille];//remplacement de malloc par new
        /* Ce code est inutile: new lance une exception de type
         * std::bad_alloc si l'allocation échoue...
         * on pourrait éventuellement envisager de la récupérer dans la fonction
         * qui déclare l'instance de notre classe, mais ici, le risque d'échec de
         * l'allocation dynamique est suffisemment restreint pour que l'on
         * puisse décider de ne pas le faire :D
        if(m_dTab == NULL)
        {
            printf("Erreur allocation mémoire pour l'objet\n");
            assert(0);
        }
        */
    }
    je suis sûr de ben comprendre, comment se fait la gestion des erreurs

    Merci
    Le C++ fournit un mécanisme de gestion des exceptions, ainsi qu'un série d'exceptions "classiques", toutes dérivées de std::exception.

    Parmi les exceptions "classiques", on trouve, entre autre (de manière non exhaustive)
    • std::bad_alloc : qui est lancée si une allocation de mémoire échoue
    • std::out_of_range
    • std::runtime_error qui est lancée (ou ses dérivées) quand un erreur "temps d'exécution" survient
    • std::logical_error qui est lancée quand une erreur due à la logique survient
    • ...

    Un exception est lancée en utilisant le mot clé throw sous une forme proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    throw type_de_l_exception_a_lancer(/* parametres éventuels */);
    Quand on sait que la logique que l'on met au point (par appels successifs de méthodes) est susceptible de lancer une exception, et que l'on est en mesure de lever l'erreur qui a provoqué l'exception, on place ce qui "risque de lancer l'exception" dans un bloc "try", et on récupère l'exception lancée dans un bloc "catch" sous 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
     
    try
    {
        /* tout ce qui peut lancer une exception */
    }
    catch(myException &e)
    {
        /* ce qu'il faut faire si une exception personnalisée est survenue */
    }
    catch(std::bad_alloc &e)
    {
        /* ce qu'il faut faire si une exception d'allocation est survenue */
    }
    catch(std::exception &e)
    {
        /* ce qu'il faut faire si une exception fournie en standard est survenue
         * (aurait pu être std::bad_alloc si on n'avait pas prévu de l'attraper 
         * séparément)
         */
    }
    catch(...)
    {
        /* ce qu'il faut faire si n'importe quelle exception non gérée séparément
         * est survenue
         */
    }
    Les différentes possibilités sont fournies à titre d'exemple, et rien n'interdit d'en mettre plusieurs l'une après l'autre, tout comme rien n'interdit de ne prévoir que d'attraper une exception particulière.

    Le tout étant de t'assurer être en mesure de gérer l'origine de l'exception lancée quand tu l'attrape

    (tu trouveras sans doute les réponses aux autres questions que tu te pose sur le sujet sur la page de la FAQ qui leur est consacrée )

    Maintenant que j'ai parlé de manière générale, parlons un peu du cas new et new[]
    new et new[] font en réalité plus que les fonctions *alloc, car il s'occupent:
    • d'allouer une zone mémoire suffisante (ce que font les fonction *alloc),
    • de vérifier si elle s'est correctement déroulée (et lance une exception de type bad_alloc si ce n'est pas le cas)
    • d'appeler le constructeur de la classe pour laquelle il alloué la mémoire
    (j'ai l'impression qu'il fait une chose supplémentaire, mais je ne suis plus sur de la manière de l'exprimer )
    Il faut noter que, alors que le C fournit le moyen de ré-allouer de la mémoire avec realloc, le C++ ne fournit aucun processus identique... il faut donc
    • allouer un nouvel espace mémoire plus (ou moins, selon le cas) important
    • copier les données qui existent et qui peuvent entrer dans ce nouvel espace
    • libérer l'ancien espace mémoire
    • assigner le nouvel espace mémoire au pointeur
    si tu veux disposer d'un mécanisme proche de realloc.

    Evidemment, il ne sert pas à grand chose de mettre tous les new dans des blocs try... catch, étant donné que, le plus souvent, si l'allocation de mémoire échoue, c'est qu'il faut sans doute trouver le moyen de libérer de la mémoire quelque part, ce qui ne peut le plus souvent se faire... qu'en amont de l'endroit où l'exception est survenue (et que, de manière générale, il n'est possible de gérer la plupart des exceptions qu'en amont de l'endroit où elles sont survenues )
    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

  9. #9
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    116
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Avril 2008
    Messages : 116
    Par défaut
    Merci pour les eclaircissements
    Coold, je vais essayer de mettre tout ça au clair et je tiens au courant
    coold

  10. #10
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    116
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Avril 2008
    Messages : 116
    Par défaut
    Bjr Kaola01 apres tes conseils avises, j'ai pu arriver à quelque chose qui je pense s'approche de la solution. Il ya bien sûr certains conseils que je n'ai pu mettre en pratique, vu le niveau du cours où on en est...par exemple le pragma once, pareil pour le type booleen, je préfère rester en accord avec le cours, nous ne somme qu'au debut du C++ et je suppose que le prof nous en parlera, c'est vrai l'an passé en java on a utilisé le type bool et je pense que ça ne va pas tardrer.
    pour le iostram.h, j'ai 1 souci car le complitaur me signale une erreur sur cet include, je ne sais pas pourquoi, j'ai dû faire comme avant avec tous les includes necessaires
    J'ai encore quelques soucis car j'introduis des int et tout semble bien se dérouler car 1 message qui me le confirme mais à l'affichage ça ne va pas.
    Je pense que l'insertion est en cause. Merci d'y jeter un coup d'oeil.

    fichier.h
    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
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    #pragma once
     
    //-----------------
    #define NON 0
    #define OUI 1
    #define EXISTE_OK 2
    #define NO_EXISTE 3
    #define OK_AD 4
    #define AD_EXISTE 5
    #define ENS_FULL 6
    //-----------------
     
    class CSetInt
    {
    public:
    	// constructeur par défaut de la classe
    	CSetInt(void);
     
    	//constructeur pour initialiser le tableau
    	CSetInt(int dTaille);
     
    	//destructeur de la classe
    	~CSetInt(void);
     
    private:
    	// taille du tableau
    	int m_dTaille;
    	//pointeur du tableau
    	int * m_pdTab;
    	// position courante
    	int m_dCurPos;
    public:
    	// fonction pour verifier si l'element existe ou pas
    	void Existe(int dNbr, int * pEx_RC);
    	// fonction d'ajout d'un nouvel element
    	void IntegerAdd(int dNbr, int * pAd_RC);
    	// fonction permettant d'avoir le nombre d'éléments de l'objet
    	int CardinalEnsemble(void);
     
    	// fonction d'affichage de l'ensemble
    	void Affiche(void);
    };
    fichier.cpp
    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
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    #include "SetInt.h"
    //#include<iostream.h>
    #include<stdio.h>
    #include<malloc.h>
    #include<string.h>
    #include<assert.h>
     
    //**************************************
    //constructeur par defaut de la classe 
    //**************************************
    CSetInt::CSetInt(void)
    : m_dTaille(0)
    , m_dCurPos(0)
    ,m_pdTab(NULL)
    {
    }
     
    //*****************************************¨*******
    //constructeur d'initialisation de l'objet
    //*************************************************
     
    CSetInt::CSetInt(int dTaille)
    //------------------------------------------------
    //initialisation de la taille du taille du tableau
    //initialisation de la position courante
    //creation du tableau
    //------------------------------------------------
    :m_dTaille(dTaille),
    m_dCurPos(0) 
    {
    	//ces 2 instructions sont deja dans la liste d'initilisation
    	/*m_dTaille = dTaille;
    	m_dCurPos =0;
    	*/ 
    	m_pdTab = (int *)malloc(sizeof(int) * m_dTaille);
    	if(m_pdTab == NULL)
    	{
    		printf("Erreur allocation mémoire pour l'objet\n");
    		assert(0);
    	}
    }
    //**************************************************
    // fonction pour verifier si l'element existe ou pas
    //**************************************************
    void CSetInt::Existe(int dNbr, int * pEx_RC)
    {
    	int dI, dExiste, dTrouve;
     
    	*pEx_RC = NO_EXISTE;
    	dExiste = NON;
    	dTrouve = NON;
    	dI = 0;
    	while( dI != m_dTaille && dTrouve == NON && dExiste == NON )
    	{
    		if(m_pdTab[dI] == dNbr)
    		{
    			dExiste = OUI;
    			dTrouve = OUI;
    			printf("l'element existe deja et ne peut etre insere !!!\n");
    			*pEx_RC = EXISTE_OK;
    		}
    		else
    		{
    			dTrouve = NON;			
    			dI++;
    		}
    	}
    }
     
    //******************************************
    // fonction d'insertion d'un nouvel element
    //******************************************
    void CSetInt::IntegerAdd(int dNbr, int * pAd_RC)
    {
    	*pAd_RC = OK_AD;
     
    	//-----------------------------------------
    	//traitement du cas ou l'ensemble est plein
    	//-----------------------------------------
     
    	if(m_dCurPos > m_dTaille)
    	{
    		printf("l'ensemble est plein et l'entier ne peut etre insere !!!\n ");
    		*pAd_RC = ENS_FULL;
    	}
     
    	//---------------------------------------------
    	//Sinon
    	//	on insere le nombre  à la position courante
    	//	on incrémente la position courante
    	//---------------------------------------------
     
    	while(m_dCurPos != m_dTaille)
    	{
    		m_pdTab[m_dCurPos] = dNbr;
    		m_dCurPos++;
    	}	
    }
    //******************************************************
    // fonction permettant d'avoir le cardinal de l'ensemble
    //******************************************************
    int CSetInt::CardinalEnsemble(void)
    {
    	int dI;
     
    	dI = 0;
    	while(dI != m_dCurPos)
    		dI++;
    	return dI;
    }
     
    //***********************************
    // fonction d'affichage de l'ensemble
    //***********************************
    void CSetInt::Affiche(void)
    {
    	for(int dI = 0; dI < m_dCurPos; dI++)
    		printf("%d", m_pdTab[dI]);
    }
     
    //************************
    //destructeur de la classe
    //************************
    CSetInt::~CSetInt(void)
    {
    	free (m_pdTab);
    }
     
    main.cpp
    #include "SetInt.h"
    #include<stdio.h>
    #include<stdlib.h>
     
    //----------------------------------------------------------------------------
    //PRJ02 Programme de gestion d'integer
    //Réaliser une classe nommée CSetInt permettant de manipuler des ensembles
    //de nombres entiers. On devra pouvoir réaliser sur un tel ensemble les 
    //opérations classiques suivantes :
     
    //•	Lui ajouter un nouvel entier; si plus de place, la fonction renvoit 
    //une valeur dans le code de retour. Si l’entier existe déjà dans l’objet
    //alors il ne devra plus y être ajouté.
    //•	Connaître son cardinal (nombre d’éléments)
    //•	Savoir si un entier donné lui appartient
    //Ici on conservera les différents éléments de l’ensemble dans un tableau 
    //alloué dynamiquement par le constructeur. Un argument (auquel on pourra 
    //prévoir une valeur par défaut) lui précisera le nombre maximal d’éléments
    //de l’ensemble.
    //•	Constructeur par défaut
    //•	Constructeur acceptant un seul paramètre spécifiant la taille de l’ensemble
    //•	Le destructeur
    //----------------------------------------------------------------------------
     
    void UseClassSetInt()
    {
    	CSetInt oEnsemble(10);//declaration et init objet de taille 10
    	int dNbr, dEx_RC, dAd_RC; 
    	char cRepInser, cChoix, cRepAffich;
     
    	printf("Voulez-vous inserer un entier (o,n) ?  ");
    	cRepInser = getchar();
    	fflush(stdin);
    	while (cRepInser != 'n')
    	{
    		printf("Entrez l'entier que vous desirez inserer : ");
    		scanf("%d", &dNbr);
    		fflush(stdin);
     
    		//------------------------------------------------------
    		//appel à la fonction qui teste si l'element existe deja
    		//s'il n'appartient pas 
    		//	alors on l'ajoute et gestion des erreurs
    		//-------------------------------------------------------
    		oEnsemble.Existe(dNbr, &dEx_RC);
    		if(dEx_RC == EXISTE_OK)
    		{
    			exit(0);
    		}
    		else 
    		{
    			oEnsemble.IntegerAdd(dNbr, &dAd_RC);
    			if(dAd_RC == EXISTE_OK)
    			{
    				printf("l'element existe deja et ne peut etre insere\n");
    				exit(0);// ne pas sortir du programme laisser la possibilite de poursuivre
    			}
    			if(dAd_RC == ENS_FULL)
    			{
    				printf("l'enemble est plein et l'element ne peut etre insere \n");
    				exit(0);//exit(0); ne pas sortir du programme laisser la possibilite de poursuivre
    			}
    		}
    		printf("L'insetion s'est bien deroulee\n");
    		printf("Voulez-vous introduire un autre entier ? (o,n) ");
    		cRepInser = getchar();
    		fflush(stdin);
    	}
     
    	printf("Voulez vous afficcher la classe (o, n) ?");
    	cRepAffich =  getchar();
    	fflush(stdin);
    	while(cRepAffich != 'n')
    	{
    		oEnsemble.Affiche();
    		printf("Voulez vous afficcher la classe (o, n) ?");
    		cRepAffich =  getchar();
    		fflush(stdin);
    	}
    }
     
    //********************
    //Programme principal
    //********************
    int main()
    {
    	char cVotreChoix;
     
    	printf("PRJ02 Class CSetInt\n");
    	printf("---------------------------------------------------\n");
    	printf("Application permettant l'ajout d'int\n\n");
    	printf("pour utiliser la classe SetInt appuyer sur 1\n");
    	printf("Pour quitter appuyer sur 2\n\n");
    	printf("votre choix : ");
    	cVotreChoix = getchar();
    	fflush(stdin);
     
    	switch(cVotreChoix)
    	{
    	case'1': UseClassSetInt();
    		break;
    	case '2': printf("Vous avez decide de quitter !!! au revoir\n");
    		exit(0);
    		break;
    	default:printf("Enter lke bon choix soit 1 ou 2\n");
    	}
    }
    Coold

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 635
    Par défaut
    Mea-culpa, je me rend compte que dans le fichier main.cpp, j'ai fait une coquille...
    j'ai voulu remplacer stdio.h par stdio, qui n'existe pas, au lieu de le remplacer par ... iostream.

    Nota: les fichiers fournis par la norme du C++ n'ont aucune extension, et, s'il existe effectivement des fichiers portant les même nom avec l'extension .h, c'est uniquement pour une question de compatibilité avec ce qui se faisait avant que la norme ne soit finalisée.

    Il faut donc écrire
    et non

    cette directive trouve tout à fait sa place, dans le code que tu présente dans fichier.cpp et dans main.cpp en remplacement des inclusions des fichiers
    • <stdio.h>
    • <malloc.h>
    • <string.h>
    • <assert.h>
    • <stdlib.h>
    (c'est fou comme deux caractères de plus peuvent foutre le bo, hein )
    En effet, les fichiers listés plus haut sont TOUS des fichiers d'en-tête issus du C, et il n'y a aucun fichier qui soit issu du C++...

    Bien que le C fasse partie d'un "sous ensemble" du C++, utiliser ces fichiers (et les fonctions auxquelles ils donnent acces) revient à accepter d'écrire un horrible code "mutant" à mis chemin entre ce qui se fait en C et ce qui se fait en C++...

    Je comprend très bien que tu aies quelques scrupules à "jouer plus vite que la musique" avec ton prof, mais, crois moi sur parole: les habitudes qu'il t'incite à prendre pour l'instant sont les pires que tu ne pourras jamais prendre... et celles dont tu auras le plus de mal à te défaire par la suite (c'est toujours comme cela, les bonne habitudes sont difficiles à prendre et facile à perdre alors que les mauvaises sont faciles à prendre et difficiles à perdre )

    Aussi, si je comprend que tu ne te sente pas forcément l'âme du justicier masqué et que tu ne souhaites pas forcément entrer en cours et lui crier
    hé prof, j'aimerais que vous nous appreniez réellement le C++ et non cette crasse d'horrible mélange de C et de C++ que vous êtes occupé à nous apprendre
    même si c'est ne y mettant un peu plus de formes (je n'oserais pas te demander de le faire, bien que je l'ai moi-même fait en son temps), je te conjure, d'essayer de suivre tous les conseils que je t'ai donné, sans exception, si tu veux réellement devenir un programmeur C++ et non quelqu'un qui "joue à bricoler" en C++.

    Enfin, comme je suis bon prince, et que j'ai l'impression que tu ne l'utilisera pas pour ton devoir, voici le code que j'écrirais:
    fichier CSetiInt.h
    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
    #ifndef CSETINT_H
    #define CSETINT_H
    #include <string>
     
    class CSetInt
    {
        public:
            CSetInt();/* constructeur par défaut (inutilisé)*/
            CSetInt(size_t s);/* constructeur réellement utilisé */
            ~CSetInt(); /*destructeur */
            const std::string& error() const;/* pour savoir ce qui a pu foirer */
            bool addInteger();/* pour ajouter un entier */
            size_t maxSize() const;/* pour connaitre le nombre maximal d'entier attendu */
            size_t count() const;/* pour connaitre le nombre d'eniters déjà introduits */
            void affiche() const;/* pour afficher les entiers introduits */
            bool existe(int search) const;/* pour savoir si un entier se trouve deja dans letableau */
        protected:
        private:
            int * m_tab;
            size_t m_pos;
            size_t m_size;
            std::string m_error;
    };
     
    #endif // CSETINT_H
    fichier CSetInt.cpp
    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
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    #include "CSetInt.h"
    #include <iostream>
    CSetInt::CSetInt():
        m_tab(NULL),
        m_pos(0),
        m_size(0)
    {
        //ctor
    }
    CSetInt::CSetInt(size_t s):
        m_pos(0),
        m_size(s)
    {
        m_tab=new int[s];
    }
    CSetInt::~CSetInt()
    {
        delete[] m_tab;
     
    }
    const std::string& CSetInt::error()const
    {
        return m_error;
    }
    bool CSetInt::addInteger()
    {
        if(m_pos==m_size)
        {
            m_error="le tableau est plein";
            return false;
        }
        std::cout<<"veuillez introduire le nombre a ajouter :";
        int i;
        std::cin>>i;
        if(existe(i))
        {
            m_error="le nombre introduit existe deja";
            return false;
        }
        m_tab[m_pos]=i;
        ++m_pos;
        m_error="";
        return true;
    }
    size_t CSetInt::maxSize() const
    {
        return m_size;
    }
    size_t CSetInt::count() const
    {
        return m_pos;
    }
    bool CSetInt::existe(int search) const
    {
        for(size_t i=0;i<m_pos;++i)
        {
            if(m_tab[i]==search)
                return true;
        }
        return false;
    }
    void CSetInt::affiche() const
    {
        std::cout<<"il y a actuellement "<<m_pos<<" elements sur "<<m_size
                 <<" possibles :";
        for(size_t i=0;i<m_pos;++i)
            std::cout<< m_tab[i]<<",";
        std::cout<<std::endl;
    }
    fichier main.cpp
    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
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    #include <iostream> //pour std::cin et std::cout
    #include <limits> //pour std::limits
    #include <stdexcept> //pour std::bad_alloc
    #include "CSetInt.h" // la classe que j'ai créée
    /* cette fonction ne sert qu'à afficher le menu et
     * à s'assurer que le choix de l'utiliateur est cohérent avec les possibilités
     * qui lui sont fournies
     * @out: choix de l'utilisateur
     */
    int menu()
    {
     
        int c=0;
        std::cout<<"Veuillez choisir l'action suivante :"<<std::endl;
        while(c<1 || c>5)
        {
            std::cout<<"1 - inserer un nouvel entier "<<std::endl
                     <<"2 - afficher les entiers deja inseres "<<std::endl
                     <<"3 -chercher une valeur donnee"<<std::endl
                     <<"4 - afficher le nombre d'entiers inseres et le nombre maximal possible"
                     <<std::endl
                     <<"5 - quitter"
                     << std::endl<<std::endl<<"Votre choix ?";
            while(!(std::cin>>c))
            {
                std::cout<<"veuillez introduire des chiffres uniquement..."<<std::endl
                         <<"Votre choix ?";
            std::cin.clear();
            std::cin.ignore( std::numeric_limits<std::streamsize>::max(), '\n' );
            }
            if(c<1 || c>5)
                std::cout<<"veuillez choisir une valeur entre 1 et 5"<<std::endl;
        }
        return c;
    }
    /* juste une pause, portable, qui attend que l'utilisateur
     * appuie sur la touche <enter>
     */
    void pause()
    {
        std::cout << "Appuyez sur entrée pour continuer...";
        std::cin.ignore( std::numeric_limits<std::streamsize>::max(), '\n' );
    }
    int main()
    {
        size_t cb;
        std::cout<<"combien d'entiers voulez vous pouvoir introduire ?";
        while(!(std::cin>>cb))
        {
            std::cout<<"veuillez introduire des chiffres uniquement..."<<std::endl;
            std::cin.clear();
            std::cin.ignore( std::numeric_limits<std::streamsize>::max(), '\n' );
            std::cout<<"combien d'entiers voulez vous pouvoir introduire ?";
        }
        try
        {
            /* A moins que le système ne soit déjà surchargé, ou que
             * l'utilisateur ne demande à pouvoir introduire un nombre
             * particulièrement élevé d'entiers, il n'y a pas de raison
             * que l'instanciation de cette classe ne lance une exception
             * Mais, autant ne pas courrir le risque ;)
             */
            CSetInt tab(cb);
            int c=0;
            while((c!=5)
            {
                c=menu(); /* on demande le choix de l'utilisateur */
                switch(c)
                {
                    case 1:
                        if(!tab.addInteger())/* si l'insertion échoue */
                            std::cout<<tab.error()<<std::endl;/* on affiche l'erreur */
                        break;
                    case 2:
                        tab.affiche();
                        break;
                    case 3:
                        int tosearch;
                        std::cout<<"Quelle valeur voulez vous chercher ?";
                        std::cin>>tosearch;
                        std::cout<<"la valeur "<<tosearch
                                 <<(tab.existe(tosearch)? " existe dans le tableau" :
                                                          " n'existe pas dans le tableau")
                        <<std::endl;
                        break;
                    case 4:
                        std::cout<<"il y a "<<tab.count()
                                 <<" elements existants sur "<<tab.maxSize()
                                 <<" possibles"<<std::endl;
                        break;
                    default:
                        break;
                }
            }
            tab.affiche();/* on affiche un dernière fois le contenu du tableau */
            pause(); /* et fait une pause */
        }
        catch(std::bad_alloc &e)
        {
            /* si l'allocation dynamique du tableau a échoué lors de l'instanciation
             * de tab, on se retrouve ici...
             * cela ne devrait pas arriver, mais, si c'est le cas
             * on affiche un message et on quitte l'application (après uen pause)
             * en indiquant au système que ca s'est mal passé
             */
            std::cout<<"une erreur est survenue lors de l'initialisation "<<std::endl
                     <<"il m'est impossible de continuer"<<std::endl;
            pause();
            return 1;//on n'a pas pu travailler correctement
        }
        return 0;/* si on arrive ici, c'est que tout s'est bien passé */
    }
    écrit en quelques minutes, mais pourtant testé
    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

  12. #12
    Membre émérite
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    780
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Mai 2006
    Messages : 780
    Par défaut
    ah le coup du prof qui apprend le C++ comme du C avec des classes...

  13. #13
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    116
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Avril 2008
    Messages : 116
    Par défaut
    c'est toujours comme cela, les bonne habitudes sont difficiles à prendre et facile à perdre alors que les mauvaises sont faciles à prendre et difficiles à perdre

    Rien à dire, je suis étonné de voir la facilité avec laquelle tout ceci tombe, je ne doute qu'il ya eu beaucoup de nuits blanches de travail là derriere, je vois ce qu'il me reste à faire en tout cas merci, je suis content d'être bien tombé, çad sur quelqu'un qui prend tout son temps et m'écrit toutes les critiques commentaires necesaires, Chapeau. Pour ce qui est du prof, je pense qu'il nous apporte les choses au compte guoute et suivant l'état d'avancement, bref merci pour tout

    Je te salue
    coold

  14. #14
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    116
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Avril 2008
    Messages : 116
    Par défaut
    Koala01, Rebonjour j'ai relevé quelques bouts de codes que je ne suis pas sûr de bien comprendre l'application est tip top, je suis content mais je sais qu'il me reste du chemin à parcourir
    cood
    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
     public:
            CSetInt();// constructeur par défaut (inutilisé)
            CSetInt(size_t s);// constructeur réellement utilisé 
            ~CSetInt(); //destructeur 
            const std::string& error() const;/*??????????*/ 
            bool addInteger();/* pour ajouter un entier */
            size_t maxSize() const;/* pour connaitre le nombre maximal d'entier attendu */
            size_t count() const;/* pour connaitre le nombre d'eniters déjà introduits */
            void affiche() const;/* pour afficher les entiers introduits */
            bool existe(int search) const;/* pour savoir si un entier se trouve deja dans letableau */
        protected:
        private:
            int * m_tab;
            size_t m_pos;
            size_t m_size;
            std::string m_error;/*???????????*/
    et dans le fichier.cpp
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    const std::string& CSetInt::error()const
    {
        return m_error;
    }
    dans le main.cpp
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     std::cin.clear();
            std::cin.ignore( std::numeric_limits<std::streamsize>::max(), '\n' );
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    std::cin.clear();
            std::cin.ignore( std::numeric_limits<std::streamsize>::max(), '\n' );//???????????
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    catch(std::bad_alloc &e)

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 635
    Par défaut
    Au fait, tu trouveras sans doute la réponse à la plupart des questions que ce code pourrait t'inspirer sur la page de la FAQ qui aborde la gestion des flux sur la console
    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

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 635
    Par défaut
    le membre m_error est simplement ce que j'ai identifiédans l'étude que j'ai faite plus haut comme "le message d'erreur"

    std::string est la classe qui gère les chaines de caractères, et qui fournit bien plus de sécurité que ce que tu pourrais obtenir avec les chaines "C style" (tableau de caractères terminé par '\0')

    la méthode error est, tout simplement, le moyen d'obtenir l'erreur qui s'est produite (si besoin)

    les lignes
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    std::cin.clear();
    std::cin.ignore( std::numeric_limits<std::streamsize>::max(), '\n' );
    sont simplement le moyen portable de vider le buffer clavier si l'entrée de l'utilisateur ne correspond pas à ce que l'application attend de lui (cf l'entrée de la FAQ qui répond à la question

    Je l'ai placé chaque fois que je me suis rendu compte que l'utilisateur risquait d'introduire quelque chose qui ne convient pas (en gros chaque fois que j'attends explicitement un entier... il serait moche qu'il introduise un caractère ou une chaine de caractères )

    Enfin, std::bad_alloc est l'exception lancée si new échoue.

    De la manière dont j'ai géré les choses, il s'agit en fait du seul problème qui peut survenir auquel je ne peux rien changer: l'application ne trouve pas suffisemment de mémoire contigue pour créer le tableau d'entiers...

    Le cas ne devrait normalement pas se présenter (cf les commentaires sur le sujet ) mais... sait on jamais
    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. Petit problème de fork
    Par osmose22 dans le forum Linux
    Réponses: 7
    Dernier message: 18/03/2007, 21h10
  2. petit probleme avec l'éditeur de builder
    Par qZheneton dans le forum C++Builder
    Réponses: 2
    Dernier message: 28/10/2004, 16h19
  3. petit probleme de requete
    Par nico33307 dans le forum Décisions SGBD
    Réponses: 2
    Dernier message: 25/08/2004, 11h36
  4. [ struts ] probleme à l'exécution
    Par flogreg dans le forum Struts 1
    Réponses: 12
    Dernier message: 23/08/2004, 12h11
  5. petit probleme dans une requte POSTGRE SQL
    Par ghis le fou dans le forum Requêtes
    Réponses: 5
    Dernier message: 08/09/2003, 13h51

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