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

  1. #1
    Membre actif
    Avatar de Sparky95
    Homme Profil pro
    Étudiant
    Inscrit en
    décembre 2016
    Messages
    194
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 23
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : décembre 2016
    Messages : 194
    Points : 202
    Points
    202

    Par défaut transformer un int to string en parametre

    bonjour,
    Je suis occupé de créer une class couleur.
    Dedans je dois créer un setter gris dont le nom doit correspondre au degré de gris. ex. setGris(20) le nom doit être "gris 20"
    Code CPP : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    int Couleur::setNom(const char*); // prototype de setNom
     
    //SETTER gris
    int Couleur::setGris(int val) {
        if(0 <= val && val <= 255){
             r = v = b = val;
             setNom();
             return 1;
         }
         return 0;
    }


    Ce que j'essayes donc de faire: est passer directement en paramètre les éléments sans passer par des intermédiaires du style new.
    J'essayes donc de faire quelque chose du style de ceci => setNom("gris" + val);
    2 problèmes avec cela
    1. setNom attends en paramètre un const char* et non un string (string n'étant pas autorisé scolairement parlent)
    2. je codes sur Solaris 11 donc la version C++ est C++98


    Je pourrais le résoudre de cette manière
    Code CPP : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    int Couleur::setGris(int val) {
        if(0 <= val && val <= 255){
            char* tmpNom = new char[9]; // gris + espace + 255 + \0 
            r = v = b = val;
            sprintf(tmpNom, "Gris %d", val);
            setNom(tmpNom);
            delete tmpNom;
            return 1;
        }
        return 0;
    }
    Mais j'essayes d'apprendre comment passe le tout directement en paramètre

    Merci d'avance pour votre aide

  2. #2
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    mai 2008
    Messages
    24 207
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : mai 2008
    Messages : 24 207
    Points : 177 371
    Points
    177 371
    Billets dans le blog
    48

    Par défaut

    Bonjour,

    Pour que le setNom fonctionne, il faudrait faire setNom(std::string("gris") + val) . Car les chaînes de caractères n'ont pas d'opérateur de concaténation.
    Aussi, il faut convertir le nombre en std::string, et c'est expliqué dans la FAQ C++

    Finalement, je n'ai pas compris pourquoi vous voulez autant éviter les new. En tout cas, je pense que votre classe de couleur ne devrait pas gérer un nom en chaîne de caractères. C'est pénible à gérer et apporte de la complexité. Pour avoir une transposition entre une couleur et un nom, je verrai bien une classe annexe qui implémenté une table de transposition ou n'importe quel autre algorithme. Ainsi, vous l'utiliserai que au besoin.
    Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui connaît l'erreur, connaît la solution.

  3. #3
    Expert éminent
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    juillet 2013
    Messages
    2 853
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : juillet 2013
    Messages : 2 853
    Points : 6 290
    Points
    6 290

    Par défaut

    Donc tu fais du C++, sans new (allocation dynamique ???), sans STL, sans les normes ... donc code directement en C alors (<- troll )

    Je te propose alors une solution C


    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
    #include <iostream>
     
    #include <cstring>
     
    #define PRINT_DEBUG std::cout << "Debug:" << std::endl << color_name << std::endl << long_name  << std::endl << other_name << std::endl;
     
     
    const size_t g_MAX_STR_LEN = 15;
     
     
    struct t_name {
    public:
     
        t_name() { reset(); }
     
     
    public:
     
        enum t_state {
            STATE_NOT_INIT = 0,
            STATE_NAME,
            STATE_OK
        };
     
     
    public:
     
        bool set_name(char* input_name, size_t input_name_len) {
            bool result;
     
            if (input_name != NULL) {
                if (input_name_len <= g_MAX_STR_LEN) {
                    strncpy(str, input_name, input_name_len);
                    str_len = input_name_len;
                } else {
                    strncpy(str, input_name, g_MAX_STR_LEN);
                    str_len = g_MAX_STR_LEN;
                }
     
                str[str_len] = '\0';
     
                state = t_name::STATE_NAME;
     
                result = true;
            } else {
                result = false;
            }
     
            return result;
        }
     
     
        bool set_level(size_t input_level) {
            bool result;
     
            if (state >= STATE_NAME) {
                size_t number_len, number;
     
                number_len = 1;
                number = input_level;
     
                while(number > 9) {
                    ++number_len;
                    number = (number / 10);
                }
     
                if ((str_len + number_len + 1) <= g_MAX_STR_LEN) {
                    size_t count_tmp;
                    char digit;
     
                    str[str_len] = ' ';
                    str_len += 1;
                    count_tmp = (str_len + number_len);
                    str[count_tmp] = '\0';
     
                    number = input_level;
     
                    while(number > 9) {
                        digit = number - ((number / 10) * 10);
                        number = (number / 10);
                        str[count_tmp - 1] = (digit + '0');
                        --count_tmp;
                    }
     
                    str[str_len] = (number + '0');
     
                    str_len += number_len;
     
                    level = input_level;
     
                    state = t_name::STATE_OK;
     
                    result = true;
                } else {
                    result = false;
                }
            } else {
                result = false;
            }
     
            return result;
        }
     
     
        bool set(char* input_name, size_t input_name_len, size_t input_level) {
            bool result;
     
            result = set_name(input_name, input_name_len);
     
            if (result) { result = set_level(input_level); }
     
            return result;
        }
     
     
        void reset() {
            str_len = 0;
            level   = 0;
            state   = t_name::STATE_NOT_INIT;
            str[0]  = '\0';
        }
     
     
    public:
     
        friend std::ostream& operator<<(std::ostream&, t_name&);
     
     
    private:
     
        char str[g_MAX_STR_LEN + 1];
        size_t str_len;
        size_t level;
     
        t_state state;
    };
     
     
    std::ostream& operator<<(std::ostream& os, t_name& name) {
        switch(name.state) {
        case t_name::STATE_NOT_INIT:
            os << "name: [not init]";
            break;
        case t_name::STATE_NAME:
            os << "name: " << name.str << " (len: " << name.str_len << ")";
            break;
        case t_name::STATE_OK:
            os << "name and level: " << name.str << " (len: " << name.str_len << ", level: " << name.level << ")";
            break;
        }
     
        return os;
    }
     
     
     
    int main (int argc, char** argv)
    {
        t_name color_name, long_name, other_name;
     
        PRINT_DEBUG std::cout << std::endl;
     
        if (!color_name.set((char*) "gray", strlen("gray"), 9768)) { std::cout << "main - warning: color_name.set false" << std::endl; }
     
        if (!long_name.set_name((char*) "MediumSpringGreen", strlen("MediumSpringGreen"))) { std::cout << "main - warning: long_name.set_name false" << std::endl; }
        if (!long_name.set_level(56)) { std::cout << "main - warning: long_name.set_level false" << std::endl; }
     
        if (!other_name.set_name((char*) "LavenderBlush", strlen("LavenderBlush"))) { std::cout << "main - warning: other_name.set_name false" << std::endl; }
        if (!other_name.set_level(2)) { std::cout << "main - warning: other_name.set_level [1] false" << std::endl; }
        if (!other_name.set_level(84)) { std::cout << "main - warning: other_name.set_level [2] false" << std::endl; }
     
        std::cout << std::endl; PRINT_DEBUG
     
        return 0;
    }

  4. #4
    Membre actif
    Avatar de Sparky95
    Homme Profil pro
    Étudiant
    Inscrit en
    décembre 2016
    Messages
    194
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 23
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : décembre 2016
    Messages : 194
    Points : 202
    Points
    202

    Par défaut

    Bonjour,
    @ LittleWhite

    Je ne voulais pas de new car je voulais voir comment faire passer l'information directement dans le paramètre du setter sans passer par une variable intermédiaire.
    Maintenant évidemment qu'il faut un new dans le setNom sinon je ne saurais garder le nom correctement.
    En se qui concerne le nom associé à la couleur c'est une consigne scolaire.
    L'on nous à fournis les nom des classes avec leur variables privé et l'on doit créer leurs setters/getters constructeurs/destructeurs ainsi que leurs méthodes.


    @foetus
    Si si j'utilises bien les new je voulais juste éviter ici car je voulais faire passer l'élément directement en paramètre. Je fais bien un new dans mon getNom.
    En ce qui concerne le string l'on ne peut pas vraiment utiliser cela :/ nous somme obligé de passer par des char*.

  5. #5
    Expert éminent
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    juillet 2013
    Messages
    2 853
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : juillet 2013
    Messages : 2 853
    Points : 6 290
    Points
    6 290

    Par défaut

    Citation Envoyé par Sparky95 Voir le message
    Maintenant évidemment qu'il faut un new dans le setNom sinon je ne saurais garder le nom correctement.
    ...
    Si si j'utilises bien les new ... Je fais bien un new dans mon getNom.
    Bien justement ton new est totalement inutile et t'oblige à faire un delete : c'est de la m*rd* en boite

    Fais comme moi : utilise un tableau classique avec une taille arbitraire char[XXX]. Soit en local dans ta fonction, soit en l'encapsulant dans une classe (comme je l'ai fait, voir le raison plus bas)


    Citation Envoyé par Sparky95 Voir le message
    En ce qui concerne le string l'on ne peut pas vraiment utiliser cela :/ nous somme obligé de passer par des char*.
    C'est de la m*rd* en boite pour 2 raisons :
    • Comme en C, tu es obligé soit de trimbaler la taille de cette chaîne et/ ou soit de l'encapsuler dans une classe/ structure (c'est d'ailleurs l'objet de la classe string)
    • Comme en C, tu vas utiliser des paramètres de type char* ou char** (si tu veux créer ta chaîne de caractères) au lieu d'une référence (string&). Sans parler de la notion de const.


    En espérant que ce soit juste le premier cours "du C avec des classes" pour ensuite passer à du C++ objet et ou template "élégant" (même C++98)

  6. #6
    Membre actif
    Avatar de Sparky95
    Homme Profil pro
    Étudiant
    Inscrit en
    décembre 2016
    Messages
    194
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 23
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : décembre 2016
    Messages : 194
    Points : 202
    Points
    202

    Par défaut

    Non on a eu du C l'année passé et concernant le fait qu'on n'ai pas le droit d'utiliser le type string ça me gonfles aussi cela simplifie pas mal de choses au niveau des chaines.
    Quand au new c'est dans mon setterNom que je le fais pas dans mon setGris.

    Voici en réalité ce que j'ai fais en attendant
    Code C++ : 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
    int Couleur::setNom(const char* val) {    if(nom)
            delete nom;
        nom = NULL;
        if(val){
            nom = new char[strlen(val) + 1];
            strcpy(nom, val);
            return 1;
        }
        return 0;
    }
    int Couleur::setGris(int val) {
        if(0 <= val && val <= 255){
            char tmpNom[9]; // gris + espace + 255 + \0
            r = v = b = val;
     
            sprintf(tmpNom, "Gris %d", val);
            setNom(tmpNom);
     
            return 1;
        }
        return 0;
    }
    le new que j'avais à la base fais dans mon setGris fut un jet rapide pour montrer une alternative. chose que j'ai vite supprimé en mettant cela dans un tableau.
    Je ne comprends juste pas pourquoi tu ne gardes pas en mémoire le nom de l'utilisateur?

  7. #7
    Rédacteur/Modérateur

    Homme Profil pro
    Network game programmer
    Inscrit en
    juin 2010
    Messages
    5 888
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : juin 2010
    Messages : 5 888
    Points : 26 021
    Points
    26 021

    Par défaut

    Pourquoi demander un int quand tu veux limiter la valeur à [0, 255] ?
    unsigned char ou uint8_t sont là pour ça
    https://en.cppreference.com/w/cpp/la...ange_of_values
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  8. #8
    Expert éminent
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    juillet 2013
    Messages
    2 853
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : juillet 2013
    Messages : 2 853
    Points : 6 290
    Points
    6 290

    Par défaut

    Citation Envoyé par Sparky95 Voir le message
    Je ne comprends juste pas pourquoi tu ne gardes pas en mémoire le nom de l'utilisateur?
    Effectivement, je ne l'avais pas vu

    Édit : ma petite structure de mon premier message peut servir à la fois pour le nom de la couleur et le nom de l'utilisateur.
    Mais effectivement , la méthode set_level est inutile pour le nom de l'utilisateur et il faudra passer par des templates pour passer la taille de la chaîne de caractères (si cela fonctionne)

    Mais encore 1 fois, c'est du mauvais C

    Pourquoi pas une allocation dynamique, mais un tableau statique de 80 à 150 caractères devrait suffire (il faut gérer le débordement comme je l'ai fait, en ne recopiant que ce qui est possible, à moins d'une autre approche).
    Mais avant de faire la destruction delete , il faut s'assurer que la nouvelle taille soit supérieure strictement à l'ancienne. Parce que dans le cas contraire, tu as une destruction/ allocation pour rien puisque, même si la taille est trop grande, elle peut contenir le nouveau nom.
    Après, tu ne veux pas stocker la taille de ta chaîne de caractères

    C'est du mauvais C , mais bon lorsque tu auras du code en production, un jour tu verras ton code être lent/ planté/ difficilement maintenable/ difficilement débuggable à cause de tous ces choix de conception : allocation dynamique à tire-larigot, manque d'informations, manque d’encapsulation - duplication de code, ...

  9. #9
    Membre actif
    Avatar de Sparky95
    Homme Profil pro
    Étudiant
    Inscrit en
    décembre 2016
    Messages
    194
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 23
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : décembre 2016
    Messages : 194
    Points : 202
    Points
    202

    Par défaut

    @Bousk
    Pas faux c'est juste que je n'y avais pas pensé. J'ai pensé à un entier et n'ai pas réfléchis plus que cela à la taille de l'élément.

  10. #10
    Membre actif
    Avatar de Sparky95
    Homme Profil pro
    Étudiant
    Inscrit en
    décembre 2016
    Messages
    194
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 23
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : décembre 2016
    Messages : 194
    Points : 202
    Points
    202

    Par défaut

    @foetus
    Etant donné que je fais du CPP en se qui concerne les allocations on doit passer par des new, car les malloc c'est du C

    je viens de voir au fait c'est le nom de la couleur hahaha et non utilisateur .

    Concernant la taille oui c'est du blindage idem d'ailleurs pour la taille des couleurs char plutot que int.
    ici j'essayais de faire au plus simple la propreté de code étant ignoré des profs.
    C'est même tout du contraire, il ne vérifies pas l'optimisation de code,...
    Juste la fonctionnalité et les erreur pouvant entrainer des bugs.

    C'est triste à dire mais un autre example en web ils n'ont rien à faire du fait qu'on puissent faire de l'injection sql dans un form ,...
    La politique est codez vite plutot que codez bien,...
    On à par exemple des cours de web(php, js) mais pas de cours de sécurité,...
    Donc si tu ne google pas les choses pour apprendre tu n'es pas au courent de comment sécuriser ton site ...
    VDM

Discussions similaires

  1. Comment transformer un numbre de string a int
    Par pierrot10 dans le forum Syntaxe
    Réponses: 2
    Dernier message: 04/12/2017, 13h40
  2. Réponses: 3
    Dernier message: 23/02/2006, 09h37
  3. [Débutant] transformer int to string
    Par rherrad dans le forum Langage
    Réponses: 2
    Dernier message: 26/11/2005, 12h23
  4. concaténer int et string
    Par liliprog dans le forum SL & STL
    Réponses: 5
    Dernier message: 13/08/2004, 16h30
  5. Int to String
    Par Tito dans le forum SQL
    Réponses: 2
    Dernier message: 21/10/2003, 14h46

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