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 :

Probleme avec un tableau dynamique


Sujet :

C++

  1. #1
    Membre averti

    Homme Profil pro
    Étudiant
    Inscrit en
    Septembre 2024
    Messages
    26
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Septembre 2024
    Messages : 26
    Par défaut Probleme avec un tableau dynamique
    j'ai un problème d'initialisation de mon tableau, voici la partie du code :

    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
     
    class Tools : public LiquidCrystal_I2C {
    private:
     
      bool   flagWrite;   
      // String ligne[nombreLignes];
      char** ligne;
      String tamponLigne;
      void _write(String value);      
      uint8_t nombreLignes;
      uint8_t nombreColonnes;    
     
    public:
      // Constructeur     
      Tools(uint8_t lcd_Addr,uint8_t lcd_cols,uint8_t lcd_rows) : LiquidCrystal_I2C(lcd_Addr,lcd_cols,lcd_rows) {
        ligne = new char*[lcd_rows];
        for (int i = 0; i < lcd_rows; i++)  ligne[i] = new char*[lcd_cols];
        nombreLignes = lcd_cols;
        nombreColonnes = lcd_rows;    
      };
    le but est de créer un tableau de chaines de caractères fixes dépendant des paramètres du constructor.

    une fois que le problème sera résolu, comment accéder a une chaine particulière dans le tableau pour lui lui assigner "coucou" par exemple ?

    Si vous pouviez m'éclairer, ce serait vraiment sympa. Je débute en C++, alors un peu d'indulgence s'il vous plait. Merci.

  2. #2
    Expert confirmé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 436
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 436
    Par défaut
    D'où sort ce type "String" ???
    Ce n'est pas un type de variable "standard".
    Ca vient des MFC ou du C++/CLI de M$ ?

    De toute façon, ce n'est pas en utilisant des tableau "à la C" (type ligne[...]) et l'allocation dynamique à la mode des années 70 (new) que vous allez faire un truc "correcte" en C++.
    Les pointeurs nus (char**), en C++, c'est très très suspect.
    Les identifiants qui commencent par un "_" (_write), c'est déconseillé en C++, mais je crois qu'en C aussi.
    Non utilisation de références (_write(String value) à la place de _write(String& value)), ça pue.


    J'espère que vous avez ces reflexe parce que vous êtes un programmeur C et pas que le cours de C++ que vous potassez vous apprend ces "conneries".

    Pour un tableau de taille variable, je vous conseille, en première implémentation, d'utiliser un simple "std::vector<>".
    Si votre cours de C++ est correct, il doit aborder ce type de classe de la STL quasiment dès le début.

  3. #3
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 145
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 145
    Billets dans le blog
    4
    Par défaut
    Mis à part que tu as écrit class, rien de ce code n'est du C++.
    Un tableau dynamique c'est std::vector.
    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.

  4. #4
    Expert confirmé
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Décembre 2015
    Messages
    1 599
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Décembre 2015
    Messages : 1 599
    Par défaut
    Bonjour,

    Tu sembles vouloir créer un tableau à 2 dimensions de caractères.
    La première question à se poser est: est-ce que le nombre de ligne et le nombre de colonnes sont des constantes de compilation? Cela peut sensiblement simplifier la gestion si c'est le cas.
    Si les 2 sont variables, c'est un peu plus lourd.

    La solution la plus triviale consiste à remplacer ligne par std::vector<std::string>> table;. Les lignes sont les éléments du vector, un std::vector<> c'est justement un tableau dont le nombre d'éléments est variable. Le constructeur s'écrit alors:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    Tools( uint8_t lcd_Addr, uint8_t lcd_cols, uint8_t lcd_rows )
        : LiquidCrystal_I2C(lcd_Addr,lcd_cols,lcd_rows)
        ,  table(lcd_rows,std::string(lcd_cols,' ')), nombreLignes{lcd_rows}, nombreColonnes{lcd_cols} {
      }
    Ça initialise la table avec chaînes composées de lcd_cols espaces.

    Ensuite pour changer une des lignes, on peut faire: table[lg] = "coucou";. Mais pour conserver le bon nombre de colonnes, il faut peut-être ajouter des espaces après le "coucou".
    Et il n'y a alors pas de new est de delete à gérer, et heureusement. Ça fait 30 ans que je fait du C++ et je ne me risque jamais à utiliser ce genre de choses.

  5. #5
    Modérateur
    Avatar de al1_24
    Homme Profil pro
    Retraité
    Inscrit en
    Mai 2002
    Messages
    9 133
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 64
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Retraité
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 9 133
    Par défaut
    L'information que herrflick13 a oublié de mentionner, c'est qu'il programme pour un microcontrôleur AVR (ATMega 328P en environnement Arduino) avec une mémoire limitée (32Ko de flash pour les programmes, 2Ko de RAM).
    La bibliothèque standard du C++ a été simplifiée et vector n'en fait pas partie.
    Quant à String, c'est une classe propre à la bibliothèque Arduino qui permet de gérer des chaînes de caractères de manière dynamique.

    Les solutions que vous proposez sont adaptées à des environnements plus "larges".
    Modérateur Langage SQL
    Règles du forum Langage SQL à lire par tous, N'hésitez pas à consulter les cours SQL
    N'oubliez pas le bouton et pensez aux balises
    [code]
    Si une réponse vous a aidé à résoudre votre problème, n'oubliez pas de voter pour elle en cliquant sur
    Aide-toi et le forum t'aidera : Un problème exposé sans mentionner les tentatives de résolution infructueuses peut laisser supposer que le posteur attend qu'on fasse son travail à sa place... et ne donne pas envie d'y répondre.

  6. #6
    Membre chevronné
    Avatar de ABD-Z
    Homme Profil pro
    Ingé. webapps embarquées – Admin/mainteneur serveur/BDD – Formateur WordPress – Desiger : logo/site
    Inscrit en
    Septembre 2016
    Messages
    302
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 27
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Ingé. webapps embarquées – Admin/mainteneur serveur/BDD – Formateur WordPress – Desiger : logo/site

    Informations forums :
    Inscription : Septembre 2016
    Messages : 302
    Billets dans le blog
    3
    Par défaut
    J'ai l'impression qu'il y a une étoile en trop. Enlève l'étoile de cette ligne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ligne[i] = new char*[lcd_cols];
    Ceci dit j'aimerais bien avoir le message d'erreur.

    Si tu as trouvé la solution, n'oublie pas de mettre en résolu

    Citation Envoyé par herrflick13 Voir le message
    j'ai un problème d'initialisation de mon tableau, voici la partie du code :

    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
     
    class Tools : public LiquidCrystal_I2C {
    private:
     
      bool   flagWrite;   
      // String ligne[nombreLignes];
      char** ligne;
      String tamponLigne;
      void _write(String value);      
      uint8_t nombreLignes;
      uint8_t nombreColonnes;    
     
    public:
      // Constructeur     
      Tools(uint8_t lcd_Addr,uint8_t lcd_cols,uint8_t lcd_rows) : LiquidCrystal_I2C(lcd_Addr,lcd_cols,lcd_rows) {
        ligne = new char*[lcd_rows];
        for (int i = 0; i < lcd_rows; i++)  ligne[i] = new char*[lcd_cols];
        nombreLignes = lcd_cols;
        nombreColonnes = lcd_rows;    
      };
    le but est de créer un tableau de chaines de caractères fixes dépendant des paramètres du constructor.

    une fois que le problème sera résolu, comment accéder a une chaine particulière dans le tableau pour lui lui assigner "coucou" par exemple ?

    Si vous pouviez m'éclairer, ce serait vraiment sympa. Je débute en C++, alors un peu d'indulgence s'il vous plait. Merci.

  7. #7
    Membre Expert
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    1 466
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 1 466
    Par défaut
    Hello,

    Effectivement, si l'on a pas accès a std::vector, il ne reste plus que les pointeurs nu.

    Par contre, instancier des tableaux de tableaux (soit un tableau 2D), ca fout le bordel dans la memoire, tous les emplacements ne seront pas contigus.
    Pour y remédier, il n'y a pas 36 solutions: Lineariser le tableau à l'aide d'une classe (considérer un tableau 1D comme un tableau 2D), et par respect du SRP, écrire une classe qui ne s'occupe que de cela:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    #include <cassert>    // Inclure si disponible
     
    class Table2D
    {
        private:
            char *mTable;
            unsigned mColonnes;
            unsigned mLignes;
        public:
            Table2D(unsigned colonnes, unsigned lignes);
            char get(unsigned x, unsigned y) const;
            void set(char value, unsigned x, unsigned y
            ~Table2D();
    };
    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
    Table2D::Table2D(unsigned colonnes, unsigned lignes):
        mTable = new char[colonnes * lignes]
    {
    }
     
    char Table2D::get(unsigned x, unsigned y) const
    {
        assert(x < mColonnes && y < mLignes);    // Pas obligatoire mais souhaitable
        return mTable[x + y * mColonnes);
    }
     
    void Table2D::set(char value, unsigned x, unsigned y)
    {
        assert(x < mColonnes && y < mLignes);    // Pas obligatoire mais souhaitable
        mTable[x + y * mColonnes] = value;
    }
     
    Table2D::~Table2D()
    {
        delete mTable[];
    }

  8. #8
    Membre Expert

    Profil pro
    Inscrit en
    Juin 2002
    Messages
    1 407
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 1 407
    Par défaut
    Citation Envoyé par Bousk Voir le message
    Mis à part que tu as écrit class, rien de ce code n'est du C++.
    Un tableau dynamique c'est std::vector.
    Je ne pense pas que le gars postule pour le prix Goncourt de la meilleure prose en C++ !
    Il cherche juste à mettre en place un dispositif et un mécanisme dont à titre perso, je ne comprend pas l'utilité.

    Pourquoi mémoriser en RAM des caractères qui, pour pouvoir être affichés, seront le moment venu mémorisés dans la RAM du LCD ?
    Pour rafraîchir l'affichage ?

    Si par contre, c'est quelque chose pour faire du transfert par bloc dans ce cas :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    // tout peut dépendre de la taille de la font utilisée... donc on prévoit des maximas pour le LCD donné
    char Screen[max_row * max_char];
    A charge après de bien segmenter le bloc (nb_rows et nb_col) pour y écrire à tel ligne et à partir de tel caractère...
    Mais je doute que ce soit ça !

  9. #9
    Expert confirmé
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    4 035
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 4 035
    Par défaut
    Hello,

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    nombreLignes = lcd_cols;
    nombreColonnes = lcd_rows;
    ça ma paraît pas très logique

    Il y a aussi effectivement une erreur à cette ligne

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ligne = new char*[lcd_rows];
    L'étoile est à retirer. Et si la mémoire est un problème, peut-être il serait mieux d'utiliser un tableau statique non ?
    Celui qui trouve sans chercher est celui qui a longtemps cherché sans trouver.(Bachelard)
    La connaissance s'acquiert par l'expérience, tout le reste n'est que de l'information.(Einstein)

  10. #10
    Membre chevronné
    Avatar de ABD-Z
    Homme Profil pro
    Ingé. webapps embarquées – Admin/mainteneur serveur/BDD – Formateur WordPress – Desiger : logo/site
    Inscrit en
    Septembre 2016
    Messages
    302
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 27
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Ingé. webapps embarquées – Admin/mainteneur serveur/BDD – Formateur WordPress – Desiger : logo/site

    Informations forums :
    Inscription : Septembre 2016
    Messages : 302
    Billets dans le blog
    3
    Par défaut
    Citation Envoyé par fred1599 Voir le message

    Il y a aussi effectivement une erreur à cette ligne

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ligne = new char*[lcd_rows];
    L'étoile est à retirer. Et si la mémoire est un problème, peut-être il serait mieux d'utiliser un tableau statique non ?
    En effet, j'ai détecté l'erreur dès le début...

    Mais les gens préfèrent diverger...

    Une personne a bien mentionné que son environnement est embarqué, donc différent d'un Cpp standard sur PC.
    Disponibilité immédiate pour une nouvelle opportunité professionnelle.
    Ingénieur couteau suisse - Site web : https://abd-z.github.io/

  11. #11
    Expert confirmé
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 287
    Par défaut
    +1 à la solution de deedolith -- quitte à tout redévelopper soi-même, ceci dit il y a des libs prêtes à l'emploi sur github qui fournissent des vecteurs simplifiés pour arduino.

    Ceci dit,

    a- c'est le mauvais delete qui est utilisé dans le destructeur -> delete[]

    b- je rendrais bien la classe [EDIT]non-[/] copiable histoire que l'OP ne tombe pas sur des erreurs qui font tout planter sur un malentendu -- EDIT: dans tous les cas en l'état sa copie va planter, et le chemin de l'effort minimal consiste à interdire la copie dans un premier temps

    c- Je préfère passer par la surcharge de l'opérateur [] plutôt que get et set -- et une fonction intermédiaire qui factorise le calcul d'offset qui qui sera inlinée par le compilo in fine

    d- on peut aussi imaginer un Tableau1D<String> (pas sûr pour "String") qui permet de bien gérer le côté: c'est un tableau de chaines et il va falloir gérer les problèmes de longueurs différentes.
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...

Discussions similaires

  1. Problème avec filtre tableau croisé dynamique
    Par sebfch dans le forum Macros et VBA Excel
    Réponses: 11
    Dernier message: 22/04/2016, 12h06
  2. Problème avec les tableau croisés dynamiques
    Par kariel dans le forum WinDev
    Réponses: 3
    Dernier message: 23/10/2014, 15h25
  3. Problème avec le tableau croisé dynamique
    Par aritas dans le forum QlikView
    Réponses: 2
    Dernier message: 25/04/2014, 10h50
  4. Réponses: 7
    Dernier message: 24/11/2006, 09h56

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