Partage
  • Partager sur Facebook
  • Partager sur Twitter

[Arduino] équivalant "explode()" de PHP

Sujet résolu
    6 juin 2014 à 9:37:20

    petit up-du-matin-qui-vas-bien !

    je suis toujours coincé sur la fonction strcat, et même si je crois comprendre pourquoi, la résolution de ce problème est encore un mystère...

    dans mon esprit, param[] est un tableau, et dans strcat, j'essai de rajouter le char "tmp" à l'index 0 de ce tableau.

    sauf que si j'ai bien pigé, en fait, mon param[key] défini la mémoire à allouer (soit 0, null, nada, kedalle) au lieu de pointer dans le tableau

    comment lui faire comprendre que mon "[key]" indique la position, et non la taille ?

    • Partager sur Facebook
    • Partager sur Twitter
      6 juin 2014 à 9:59:37

      Je vais essayer de reprendre en rapide... Une chaine de caracteres est un tableau de char. Un tableau de char se declare comme ca char tableau[TAILLE]; avec TAILLE le nombre de caracteres a stocker (+1 pour la fin de chaine). On peut faire autrement et plus dyamique mais c'est plus complique. Un tableau de char, c'est aussi un pointeur. donc ecrire *tableau ou tableau[0] c'est pareil. Tout comme *(tableau+2) et tableau[2] sont aussi pareil. Si je veux stocker "bonjour", j'ai besoin d'un tableau de 8 caracteres (7 lettres + fin de chaine \0). Ca fera

      tableau[0] = 'b';
      tableau[1] = 'o';
      tableau[2] = 'n';
      tableau[3] = 'j';
      tableau[4] = 'o';
      tableau[5] = 'u';
      tableau[6] = 'r';
      tableau[7] = '\0';
      

      Si je bricole en deplacant la fin de chaine, je peux recuperer que bon par exemple :

      tableau[3] = '\0';
      // affichera "bon"
      tableau[0] = 'b';
      tableau[1] = 'o';
      tableau[2] = 'n';
      tableau[3] = '\0';
      tableau[4] = 'o';
      tableau[5] = 'u';
      tableau[6] = 'r';
      tableau[7] = '\0';
      

      Maintenant pour strcat. La fonction se sert du caractere de fin de chaine pou savoir ou s'arreter. Si tu lui donnes une chaine sans, ca ne marche pas. Il faut donc :

      • Lui donner en premier argument le pointeur vers une chaine de caractere (dans notre cas tableau)
      • Lui donner en deuxieme argument le pointeur vers la deuxieme chaine de caractere a concatener dans la premiere.

      Dans cette ligne: strcat(param[key],tmp);//concaténation Tu lui donnes :

      • Un caractere en premier parametre. Ca ne peut pas marcher. Donne lui plutot juste param.
      • Un pointeur vers un tableau avec une seule case, qui ne possede donc pas de caractere de fin de chaine. Reprend l'exemple du tableau que j'ai donne dans des posts plus tot :)

      Je sais pas si je suis totalement clair dans l'explication, ces histoires de pointeur c'est toujours un peu delicat a expliquer a l'ecrit...

      -
      Edité par Eskimon 6 juin 2014 à 10:00:15

      • Partager sur Facebook
      • Partager sur Twitter

      Retrouvez moi sur mon blog et ma chaine Youtube !

        6 juin 2014 à 10:14:03

        donc, si je suis bien, si je veut faire un tableau qui contient plusieurs "mots", en fait, je devrais faire un array d'array ? genre :

        char tableau[][]={"je","suis","une","quiche","en","C"};

        ?

        et si veut veut pointer sur le mot "quiche", je devrais taper :

        tableau[3]

        et si je veut que le "h" :

        tableau[3][4]

        j'ai bon ?

        • Partager sur Facebook
        • Partager sur Twitter
          6 juin 2014 à 11:02:00

          super !

          j'ai donc initialiser mon tableau comme ceci :

          char *param[30][5]={{"A"},{"B"},{"C"},{"D"},{"E"}};

          soit (si j'ai tout compris bien sûr :-°) un tableau qui peut contenir 30 char, répartis en 5 sous-array

          ensuite (je met que le case default, key vaut 0 à ce moment là)

          default:
              tmp[0] = car;//pointeur
              strcat(param[key],tmp);//concaténation
              Serial.println(param[key]);
              break;

          je charge tmp dans le l'index 0 du tableau (soit, si je me gourre pas, là ou se trouve "A")
          et ben j'ai quand même droit à une erreur....

          "error: cannot convert 'char**' to 'char*' for argument '1' to 'char* strcat(char*, const char*)"

          • Partager sur Facebook
          • Partager sur Twitter
            6 juin 2014 à 11:17:02

            pour la declaration de "param", tu as :

            • Une etoile en trop
            • Il faut inverser le 30 et le 5... en gros, le premier indique le nombre de sous array et le deuxieme la taille de ces derniers.

            pour ton strcat... essaie ca : strcat(&param[key],tmp); le & passera l'adresse plutot que la valeur... pour le deuxieme argument ca devrait etre bon (mais il faut que tu sois sur que tmp[1] soit un caractere de fin de chaine

            • Partager sur Facebook
            • Partager sur Twitter

            Retrouvez moi sur mon blog et ma chaine Youtube !

              6 juin 2014 à 12:00:34

              ha oui, y a du mieux ! Merci !

              je devrais donc déclarer <tmp[1]="\0";> non ?

              y a du mieux, merci Eskimon, p*tain, ça m'oppresse d'avoir la logique du code dans ma tête, et d'être totalement incapable de l'exprimer tout seul :colere:

               Pour &param[key], si je met le "&", ça hurle, si je le met pas, ça marche à peu près comme il faut...:o

              quelques petit pb encore,voici le fichier :

              NAV|MIN|RED|A|Circulaire
              NAV|MIN|BLUE|B|Defonceuse
              NAV|MAX|PURPLE|C|Ponceuse

              et les résultats du Serial :

              NAV
              MIN
              RED
              A
              *Circulaire
              NAV
              MIN
              BLUE
              B
              *Defonceuse
              NAV
              MAX
              ëPURPLE
              C

              alors :

              les "*" sont mal placé, ça, j'ai compris la boulette, ça va être rectifier

              il manque le dernier param, "ponceuse", je pense que c'est dû au fait que mon fixhier n'a pas de retour à la ligne à la fin, ça va se corriger aussi

              par contre, le "ë" de "ëPURPLE", je le comprend pas...je détecte rien de particulier dans le fichier, ni dans le code qui pourrais généré ça..o_O

              et dernière question, quand on déclare tableau[5][30], les 30 représente l'espace total àlloué à la totalité de l'index principal, ou alloué à chaque sous-index ?

              • Partager sur Facebook
              • Partager sur Twitter
                6 juin 2014 à 12:11:58

                et dernière question, quand on déclare tableau[5][30], les 30 représente l'espace total àlloué à la totalité de l'index principal, ou alloué à chaque sous-index ?

                Chaque chaine pourra faire 30 caracteres (29+1). Donc tu prends 30*5 = 150 octets en memoires pour ce tableau.

                par contre, le "ë" de "ëPURPLE", je le comprend pas...je détecte rien de particulier dans le fichier, ni dans le code qui pourrais généré ça..o_O

                C'est marrant moi j'aurais dit que c'etait le meme probleme que les * des autres mots... faudrait voir le code...

                je devrais donc déclarer <tmp[1]="\0";> non ?

                Tu mets des simples quotes a la place des doubles et c'est ca.

                • Partager sur Facebook
                • Partager sur Twitter

                Retrouvez moi sur mon blog et ma chaine Youtube !

                  6 juin 2014 à 14:06:52

                  ok, je peut donc descendre à [15] pour l'array ! (y aurais moyen de définir la longueur de chaque index séparément (genre le premier fait 15, le second fait 1, ...)?)

                  pour ëPURPLE, j'ai plus ce soucie pour le moment, mais j'en ai un tout beau tout neuf à la place !

                  voici le code actuel ('tention les yeux :lol:):

                  char path[30] = "";
                  char tmp[2] = " ";
                  char param[5][15]={{""},{""},{""},{""},{""}};
                  int key=0;
                  
                  char loadMenu(char *fileName)
                    {sprintf(path, "Menu/%s.txt", fileName);
                    myFile = SD.open(path);
                    if(myFile)//si le fichier existe
                      {
                      while (myFile.available())//boucle tant qu'il y a du contenu
                        {
                        char car = myFile.read();//reception du char
                        switch (car)//gare de triage
                          {
                          case '|':
                            key++;//incrémentation du tableau
                            break;
                          case '\n':
                            Serial.println(param[0]);//lecture de param[0]
                            Serial.println(param[1]);//lecture de param[1]
                            Serial.println(param[2]);//lecture de param[2]
                            Serial.println(param[3]);//lecture de param[3]
                            Serial.println(param[4]);//lecture de param[4]
                            Serial.println('*');
                            break;
                          default:
                            tmp[0] = car;//pointeur
                            strcat(param[key],tmp);//concaténation
                            break;
                          }
                        }
                      myFile.close();//fermeture file
                      }
                    else
                      {
                      sprintf(path, "Le Menu %s est inaccessible !", fileName);//erreur de lecture
                      Serial.println(path);
                      }
                    }

                  et le résultat obtenu :

                  NAV
                  MIN
                  RED
                  A
                  Circulaire
                  *
                  NAV
                  MIN
                  RED
                  A
                  Circulaire
                  NAV
                  *

                  alors, 2 soucies :

                  • sur les 3 lignes de mon fichier, je n'obtient que la première ligne et une copie de la première ligne :colere2:
                  • le script n'a bouclé que 2 fois au lieu de 3 :euh:

                   une idée du pourquoi du comment ?

                  -
                  Edité par Air_maX 6 juin 2014 à 14:09:01

                  • Partager sur Facebook
                  • Partager sur Twitter
                    6 juin 2014 à 15:31:46

                    dans ton case('\n') il faut que tu remettes key a 0 !

                    • Partager sur Facebook
                    • Partager sur Twitter

                    Retrouvez moi sur mon blog et ma chaine Youtube !

                      6 juin 2014 à 15:56:10

                      bien vu, un oublie !^^

                      par contre, faut aussi que je vide mon tableau pour pas que les nouvelles valeurs se rajoutent aux anciennes :

                       case '\n':
                                Serial.println(param[0]);
                                Serial.println(param[1]);
                                Serial.println(param[2]);
                                Serial.println(param[3]);
                                Serial.println(param[4]);
                                Serial.println('*');
                                key=0;
                                param[5][15]={{""},{""},{""},{""},{""}};
                                break;

                      ...et là, c'est le drame !

                       error: cannot convert '<brace-enclosed initializer list>' to 'char' in assignment

                      AKEWA ?

                      -
                      Edité par Air_maX 6 juin 2014 à 15:57:13

                      • Partager sur Facebook
                      • Partager sur Twitter
                        6 juin 2014 à 16:21:57

                        L'initialisation d'un tableau avec des accolades et autre n'est autorisée qu'à la déclaration de ce celui-ci.

                        Après, tu dois utiliser toutes les fonctions de manipulation ou des crochets.

                        // POSSIBLE (CAR DECLARATION) :
                        char param[5][15]={{""},{""},{""},{""},{""}};
                        
                        // IMPOSSIBLE :
                        param[5][15]={{""},{""},{""},{""},{""}};
                        
                        // POSSIBLE :
                        param[0][0] = '\0'; // Caractère fin de chaine en pos 0 => chaine vide
                        param[1][0] = '\0'; // Caractère fin de chaine en pos 0 => chaine vide
                        param[2][0] = '\0'; // Caractère fin de chaine en pos 0 => chaine vide
                        param[3][0] = '\0'; // Caractère fin de chaine en pos 0 => chaine vide
                        param[4][0] = '\0'; // Caractère fin de chaine en pos 0 => chaine vide

                        Tu peux aussi utiliser une petite boucle pour faire plus joli.

                        • Partager sur Facebook
                        • Partager sur Twitter
                          6 juin 2014 à 17:46:28

                          ou alors, tu écris dedans sans te soucier et tu y mets un caractère de fin de chaine au bon endroit... nettement plus crade, mais fonctionnel. et ça a l'avantage de pas prendre de temps pour remplir un tableau de 15*5 de 0...

                          EDIT j'avais mal lu ton post lorrio. j'avais cru que tu lui avais mis un truc du style de:

                          for (i=0;i<5;i++){      //dans chaque mot,
                              for (j=0,j<15,j++){ // pour chaque lettre
                                  param[i][j]='0' //on met 0 comme caractere
                              }
                          }

                          c'est ça qui est vraiment chronophage et pas intéressant dans son cas

                          -
                          Edité par remace 6 juin 2014 à 17:50:59

                          • Partager sur Facebook
                          • Partager sur Twitter

                          oui. non. enfin je regarde et je te dis.

                            6 juin 2014 à 18:47:08

                            yes !

                            merci lorrio !

                            j'ai fait ma boucle et mtn, tout marche correctement !:)

                            (j'aurais aussi pu faire des bêtes copier-coller de tes premiers posts, mais je voulais trouver et comprendre se qui marche ou pas et pourquoi ;))

                            j'ai enfin mon lecteur de fichier opérationnelle !! mon(enfin, presque "mon") premier code qui marche sous Arduino !

                            bon, étape suivante, continuer la création de la lib qui transforme les param[] en bouton cliquable (presque opé), et gérer la navigation(là j'ai encore quelques gros doutes)...

                            dernier point pour essayer d'optimiser un peu  :

                            dans l'initialisation du tableau, j'ai déclarer [15] car j'ai un index du tableau qui va s'approcher de ça, mais j'ai aussi des valeurs beaucoup plus petites, puis-je préciser la taille de chaque index, ou est-on forcer d'en donner qu'un seul, qui vaudra pour tout le tableau ?

                            -
                            Edité par Air_maX 6 juin 2014 à 18:51:14

                            • Partager sur Facebook
                            • Partager sur Twitter
                              6 juin 2014 à 19:06:23

                              Pour ce genre de tableau, tu es obligé de d'avoir une taille fixe pour tout le monde.

                              tab[5][15] est une suite continue de 5*15 octets, c'est en dure, tu ne peux pas changer.

                              D'ailleurs, si tu écris bat[0][16] = 'b';, ce qui est strictement interdit, ça va déborder sur la deuxième chaine du tableau et ça revient à écrire tab[1][2] = 'b';

                              Si tu veux des éléments variables, il te faut des chaines indépendantes, et un tableau de pointeurs les regroupant.

                              Cependant, chaque pointeur occupe 2 octets donc tu ne seras pas forcément gagnant.

                              Un petit exemple de ce que tu peux faire :

                              char tab_0[8] = "";
                              char tab_1[16] = "";
                              char tab_2[4] = "";
                              char tab_3[8] = "";
                              char tab_4[16] = "";
                              
                              char* tab[] = { tab_0, tab_1, tab_2, tab_3, tab_4 };

                              Dans ce cas, ceci occupera 8+16+4+8+16+10= 62 octets en RAM.

                              -
                              Edité par lorrio 6 juin 2014 à 19:07:37

                              • Partager sur Facebook
                              • Partager sur Twitter
                                6 juin 2014 à 19:39:09

                                je comprend, ce qui me gène c'est que seul un seul des index du tableau atteindra (au max) 14 octets, les autre tourne entre 2 et 4, faut que je fasse le calcul pour savoir quelle solution est la plus "rentable"

                                Edit :

                                tableau[5][15]{...};

                                75 Octets

                                char tab0[15]="";
                                char tab1[2]="";
                                char tab2[4]="";
                                char tab3[4]="";
                                char tab4[4]="";
                                char tableau[]={tab0,tab1,tab2,tab3,tab4};

                                39 Octets

                                AND THE WINNER IS.....lorrio !;)

                                Merci à vous 4 pour votre patience de fous ! (et pardon d'avance, mais sûrement à très bientôt ! :D)

                                -
                                Edité par Air_maX 6 juin 2014 à 21:18:07

                                • Partager sur Facebook
                                • Partager sur Twitter
                                  6 juin 2014 à 21:25:30

                                  ATTENTION ! Une chaine de caractère doit toujours se terminer par un caractère de fin de chaine \0.

                                  Si tu écris char tab[2], alors tab pourra retenir une chaine que d'un chaine caractère (le second étant réservé pour \0)

                                  • Partager sur Facebook
                                  • Partager sur Twitter
                                    6 juin 2014 à 21:46:11

                                    je l'avais noté ! mon tab4[2] ne contient par exemple qu'un seul caractère (mais t'a eu raison de me le répéter encore une fois cela dit, ça fera au moins une notion d'intégré dans ma mémoire :D)
                                    • Partager sur Facebook
                                    • Partager sur Twitter
                                      13 juin 2014 à 18:29:51

                                      Bonjour à tous !

                                      Petite séance de rabe sur ce sujet, suite à une MAJ de mon script qui fait du caca !:D

                                      J'ai voulu rajouter dans mon fichier texte 2 param supplémentaire, dédié non pas au contenu du menu, mais au menu lui-même :

                                      BLUE|Accueil
                                      NAV|CIRCULAIRE|MIN|RED|A|Circulaire
                                      NAV|DEFONCEUSE|MIN|BLUE|B|Defonceuse
                                      NAV|PONCEUSE|MAX|PURPLE|C|Ponceuse
                                      

                                      La première ligne défini donc le menu (Background|Title)

                                      Les autre lignes définissent les boutons présent dans ce menu (Type|Target|Size|Background|Logo|Label)

                                      voici le résultat Sérial  :

                                      BLUE
                                      Accueil
                                       
                                      NAV
                                      CIRCULAIRE
                                      MIN
                                      RED
                                      A
                                      Circulaire
                                      
                                      
                                      DEFONCEUSE
                                      MIN
                                      BLUE
                                      B
                                      Defonceuse
                                      
                                      LE
                                      PONCEUSE
                                      MAX
                                      PURPLE
                                      C
                                      Ponceuse

                                      alors, je constate 2 erreurs que je ne pige pas :

                                      il manque un "NAV" au deuxième block de bouton, j'ai une ligne vide à la place :euh:

                                      le "NAV" du dernier block à été remplacé par "LE", qui sort juste de nulle-part !o_O

                                      Allé, sans plus attendre, voila ce que j'ai commis :;)

                                      char path[15]="";
                                      char tmp[2]=" ";
                                      char Type[4]="";
                                      char Target[15]="";
                                      char Size[4]="";
                                      char Color[4]="";
                                      char Logo[2]="";
                                      char Label[15]="";
                                      char* menuParam[2]={Color,Label};
                                      char* buttonParam[6]={Type,Target,Size,Color,Logo,Label};
                                      int key=0;
                                      
                                      char loadMenu(char *fileName){
                                        sprintf(path, "Menu/%s.txt", fileName);
                                        myFile = SD.open(path);
                                        if(myFile){
                                          boolean paramMenu=true;
                                          while(myFile.available()){
                                            char car = myFile.read();//reception du char
                                            switch(car){
                                              case '|':
                                                key++;//incrémentation du tableau
                                                break;
                                              case '\n':
                                                if(paramMenu){
                                                  Serial.println(menuParam[0]);
                                                  Serial.println(menuParam[1]);
                                                  Serial.println(' ');
                                                  paramMenu=false;
                                                  for(int i=0;i<2;i++){
                                                    menuParam[i][0]='\0';}}
                                                else{
                                                  Serial.println(buttonParam[0]);
                                                  Serial.println(buttonParam[1]);
                                                  Serial.println(buttonParam[2]);
                                                  Serial.println(buttonParam[3]);
                                                  Serial.println(buttonParam[4]);
                                                  Serial.println(buttonParam[5]);
                                                  Serial.println(' ');
                                                  for(int i=0;i<6;i++){
                                                    buttonParam[i][0]='\0';}}
                                                key=0;//RAZ du tableau
                                                break;
                                              default:
                                                tmp[0] = car;//pointeur
                                                if(paramMenu){
                                                  strcat(menuParam[key],tmp);}
                                                else{
                                                  strcat(buttonParam[key],tmp);}
                                                break;}}
                                          myFile.close();}//fermeture file
                                        else
                                          {sprintf(path, "Le Menu %s est inaccessible !", fileName);//erreur de lecture
                                          Serial.println(path);}}
                                      
                                      void setup(){
                                        Serial.begin(9600);
                                        if(!SD.begin(SDpin)){
                                          Serial.println("SD failed");}
                                        else{
                                          loadMenu("HOME");}}

                                      je vous remercie par avance pour votre aide !:)

                                      • Partager sur Facebook
                                      • Partager sur Twitter
                                        13 juin 2014 à 19:54:09

                                        Bonjour,

                                        tu déclaré dans ton programme:

                                        char Color[4]="";

                                        Mais tes couleurs ont plus que 3 caractères.

                                        Je ne sais pas si le problème vient de la mais essaye et tu verras.

                                        Je m'excuse pour la présentation, j'ai écrit depuis mon smartphone.

                                        -
                                        Edité par Yoyojoss 13 juin 2014 à 19:58:05

                                        • Partager sur Facebook
                                        • Partager sur Twitter
                                          13 juin 2014 à 20:01:21

                                          pinaise !

                                          t'as pas des yeux de taupe toi !:D

                                          Merci beaucoup  c'étais vraiment un truc bête, j'aurais jamais cru que ce genre d’erreur puisse provoquer ce genre de réaction, du coup, je cherchais pas du tout dans cette direction !

                                          Merci encore, t'a mis dans le mille !

                                          • Partager sur Facebook
                                          • Partager sur Twitter

                                          [Arduino] équivalant "explode()" de PHP

                                          × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                                          × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                                          • Editeur
                                          • Markdown