Pointeur tableau 2D

Bonjour,
je travaille actuellement sur les pointeurs d'adresse de tableau. Sur le tableau classique, je n'ai pas de problèmes.

String *pPointeurTableau;
String cez[4] {"c0", "c1", "c2", "c3"};

  pPointeurTableau = cez; 
  for (i = 0; i < 4; i++)
  {
    Serial.println(pPointeurTableau[i]);
  }

La ou je bloque, c'est sur les tableau 2D

String *pPointeurTableau;
String c[2][4] {{"d0", "d1", "d2", "d3"},
    {"d4", "d5", "d6", "d7"}
  };

  pPointeurTableau [2][4] = c;
  Serial.println("imprime tableau par le pointeur:");
  for (i = 0; i < 4; i++)
  {
    Serial.println(pPointeurTableau[0][i]);                // Affiche la 1ere ligne
  }

  Serial.println("imprime tableau par le nom:");
  for (i = 0; i < 4; i++)
  {
    Serial.println(c[0][i]);                // Affiche la 1ere ligne
  }

et la ça ne fonctionne pas. Je pense avoir un problème sur la déclaration du pointeur, mais je ne trouve pas.

Un petit coup de pouce?
Merci à vous.

la ligne

  pPointeurTableau [2][4] = c;

est incorrecte.
Comme précédemment, tu dois écrire   pPointeurTableau = c;pour que ton pointeur vise le début du tableau.

En plus, dans un tableau Toto[N], on ne peut accéder qu'aux éléments 0 à N-1

biggil:
la ligne

  pPointeurTableau [2][4] = c;

est incorrecte.
Comme précédemment, tu dois écrire   pPointeurTableau = c;pour que ton pointeur vise le début du tableau.

En plus, dans un tableau Toto[N], on ne peut accéder qu'aux éléments 0 à N-1

Mon tableau est de type Toto[M][N].

Si je ne met pas les 2 dimension au pointeur, ça ne compile pas.
Erreur:
"cannot convert 'String [2][4]' to 'String*' in assignment"

Je cherche, mais je ne trouve pas...

autant pour moi, il faut écrire

pPointeurTableau = &c[0][0]

pour positionner ton pointeur sur le 1er élément du tableau

Mais bon, dans ton code, ce pointeur n'amène rien de plus, tu accèdes bien plus simplement aux éléments du tableau par c[p][q].

Les pointeurs sur les tableaux multidimensionnels, c'est compliqué, je te suggère de googler "pointeur tableau deux dimensions"...

Dans mon code, j'ai des fichier texte sur une SD avec les quel je renseigne 3 tableaux de taille et contenu différant.

Ce que j'essaye de faire, c’est une fonction centrale qui utilise un pointeur pour remplir le tableau.

Là, c'est juste un petit bout de code qui me permet de valider la méthode.

Je viens de tester pPointeurTableau = &c[0][0] mais il semble que le probléme est le même, il pointe ailleurs dans la mémoire.

Jusqu'à présent mes recherches étaient sur "arduino pointeur tableau 2d". Je vais prendre plus large comme tu le suggérer.
Merci

Je viens enfin de trouver la solution à ce que je recherche.
Je créé un tableau, puis un pointeur qui pointe sur le début du tableau et enfin je l'affiche.

Un petit code:

#include <stdio.h>    /* Autorise l'emploi de scanf et de printf. */

#define ROW_COUNT(array)    (sizeof(array) / sizeof(*array))                          // Calcule le nombre de lignes du tableau
#define COLUMN_COUNT(array) (sizeof(array) / (sizeof(**array) * ROW_COUNT(array)))    // Calcule le nombre de colonnes du tableau

int i, l, x, y;
String (*pPointeurTableau)[3][4];                               // Déclaration du pointeur de tableau
char buffer[30];                                                // Buffer sprintif

// -------------------------------------------------------------
void setup() {
  Serial.begin(9600);                                           // Initialise le port série
  Serial.println("Pret...");

  Serial.println("// ---------------------");
  String c[3][4] {{"d0", "d1", "d2", "d3"},
                  {"d4", "d5", "d6", "d7"},
                  {"d8", "d9", "d10", "d10"}};
  x = ROW_COUNT(c);
  y = COLUMN_COUNT(c);
  sprintf(buffer, "X/Y du tableau c: X=%d, Y=%d", x, y);
  Serial.println(buffer);
  Serial.println("// ---------------------");
  pPointeurTableau = &c;                                        // Pointe sur un tableau 2d
  Serial.println("imprime le tableau en utilisant\nun pointeur de tableau:");
  for (l = 0; l < x; l++)
  {
    for (i = 0; i < y; i++)
    {
      sprintf(buffer, "ligne%d pos%o: ", l, i);
      Serial.print(buffer);
      Serial.println(pPointeurTableau[0][l][i]);                // Affiche la 1ere ligne
    }
  }
  Serial.println("// ---------------------");
}

// -------------------------------------------------------------
void loop() {
  // put your main code here, to run repeatedly:

}

N’utilisez pas des objets String mais des tableaux de char

Écrire n’importe où dans la mémoire de votre instance de la classe String n’est pas une bonne idée - au minimum il faudrait lui demander le pointeur mémoire c_str() sur le tableau de char associé

Merci pour votre réponse.
Je comprend ce que vous m'expliquez, mais malheureusement les string son trop impliqué dans mon projet(Beaucoup trop de lignes à réécrire).
Sur les prochains, je verrai les choses autrement.

Depuis hier, je parcours, lie, cherche, expérimente une méthode pour:
Utiliser une fonction qui soit capable de traiter des tableaux 2d de différant taille. La méthode que je souhaite employer est de pointer sur le tableau, de le mètre en paramètre de la fonction et de le traiter.

Ce que j'arrive à faire:

String e[2][4] {{"e0", "e1", "e2", "e3"},
    {"e4", "e5", "e6", "e7"}
  };
const int Xx ROW_COUNT(e);
const int Yy COLUMN_COUNT(e);

PointeAffichTab2D ((String*) e, Xx, Yy);
void PointeAffichTab2D (String *Tab, const int X, const int Y)
{
  for (l = 0; l < x; l++)
  {
    for (i = 0; i < y; i++)
    {
      sprintf(buffer, "ligne%d pos%d: ", l, i);
      Serial.print(buffer);
      Serial.println(Tab[l][i]);
    }
  }
}

A force de faire et défaire, j'ai la tête comme un compteur à gaz!

Personne pour m'aider?
Merci par avance

Je patauge, mais:

L'idée:
Récupérer l'adresse du tableau dans "char adr" calculer la taille du tableau dans "int x, y",
Appeler la fonction et lui donner les paramètres,

Dans la fonction:
Créer un pointeur de tableau 2d,
Pointer sur l'adresse.

  Serial.begin(9600);                                           // Initialise le port série
  Serial.println("Pret...");

  Serial.println("// ---------------------");
  String c[3][4] {{"d0", "d1", "d2", "d3"},
    {"d4", "d5", "d6", "d7"},
    {"d8", "d9", "d10", "d10"}
  };
  x = ROW_COUNT(c);
  y = COLUMN_COUNT(c);
  sprintf(buffer, "%p", &c);
affichTabPointeur(buffer, x, y);

}


void affichTabPointeur(char adr, int x, int y)
{
  String (*pTab2D) [x][y] = adr;
  sprintf(buffer, "X/Y du tableau c: X=%d, Y=%d", x, y);
  Serial.println(buffer);
      Serial.println(pTab2D[0][0][0]);                // Affiche la ligne
}

Il se passe bien quelque chose, mais visiblement je ne dois pas pointer sur mon tableau, mais sur l'adresse de "adr"
A suivre...
Suis-je sur le bon chemin?

Je reste sur la même voie. Mais toujours rien. Pour passer l'adresse sur là-quel je pointe, je converti en int, puis dans la fonction je créé le pointeur sur la conversion hexa du int.

Ça ne fonctionne toujours pas.

void setup() {
  Serial.begin(9600);                                           // Initialise le port série
  Serial.println("Pret...");

  Serial.println("// ---------------------");
  String c[3][4] {{"d0", "d1", "d2", "d3"},
    {"d4", "d5", "d6", "d7"},
    {"d8", "d9", "d10", "d10"}
  };
  x = ROW_COUNT(c);
  y = COLUMN_COUNT(c);
  sprintf(buffer, "Adresse du tableau: %p", &c);
  Serial.println(buffer);
  sprintf(buffer, "Convertion en dec: %u", &c);
  Serial.println(buffer);

  sprintf(buffer, "%u", &c);
  val = atoi(buffer);
  Serial.println(val);
  affichTabPointeur(val, x, y);
  Serial.println("// ---------------------");

}

void affichTabPointeur(int adr, int x, int y)
{
  Serial.println("\nFonction affichTabPointeur:");
  Serial.print("Valeur de val: ");
  Serial.println(adr);

  char valAdr [10];                                             // Creation du tempon
  sprintf(valAdr, "%p", adr);                                   // Convertion dec to hex
  Serial.print("Valeur de valAdr: ");
  Serial.println(valAdr);
  String (*pTab2D) [x][y] = sprintf("%X", valAdr);              // Pointe sur l'adresse du tableau
  Serial.println("");
  sprintf(buffer, "Adresse pointee: %X", pTab2D);
  Serial.println(buffer);


  sprintf(buffer, "X/Y du tableau c: X=%d, Y=%d", x, y);
  Serial.println(buffer);
  Serial.println(pTab2D[0][1][1]);                // Affiche la ligne*/
}

A suivre...

Bonjour,
est-ce que votre tableau est de taille fixe (connue à la compilation) ?
Si la taille ne change pas, je conseille ceci (connaissez-vous les références "&" ?)

typedef String StringArray32[3][2];


void changetab(StringArray32 & tab, i, j, String & s)
{
   tab[i][j]=s;
}

 
...

   StringArray32 array = {{ "a", "b"}, {"c","d"}};
   changetab(array, 1,1,"z");

Merci pour votre réponse. Je connais le '&' pour avoir l'adresse d'une variable notamment mais pas comme ceci. Je vai regarder.
Actuellement, mon tableau est de taille fixe, mais à terme, je voudrai créer une fonction qui extrait des données dans un fichier '.txt' sur une SD et renseigner des tableaux. Cette fonction utilisera plusieurs fichiers avec leurs tableau associé. Dans les paramètres, je donne le .txt, le tableau avec ses dimensions.

Bonsoir,
il faudra faire autrement dans ce cas car la syntaxe décrite ci-dessus ne fonctionne qu'avec des tailles connues à l'avance.
Si la taille est inconnue à la compilation il y a deux possibilités:

  • soit utiliser un tableau de taille fixe maximale et ne remplir qu'une partie,
  • soit utiliser une allocation dynamique avec new ou malloc
    le nombre de colonnes est-il connu à l'avance ou pas non plus ?

Pour le moment je ne suis pas sur mon projet final, mais, je connais la taille des tableaux à utiliser que je renseigne avec 'x' et 'y'.
Je travaille sur le projet dont la source est disponible en #12. Je tâtonne pour trouver comment accéder aux valeurs de mon tableau. J'ai l'adresse de départ dans ma fonction, maintenant reste à afficher / exploiter le contenu.

Edit: Oup's je voulais dire en poste #11.

Je ne comprends pas votre ligne

  String (*pTab2D) [x][y] = sprintf("%X", valAdr);

Vous déclarez un pointeur sur un tableau de x*y objets de type String et vous semblez vouloir y ranger (mais dans quelle case???) le résultat de sprintf...
Attention !!!! Les tableaux de taille "variable", du genre (ce que vous faites avec x et y):

void fonction(int i)
{
   String tab[i]; 
}

sont supportés par certaines versions du langage mais ce n'est pas standard du tout et très controversé, je vous déconseille fortement d'utiliser ceci... n'utilisez que des tableaux où la taille en mémoire est un vrai chiffre, pas une variable. D'ailleurs que pensez-vous qu'il va se passer si je change i par la suite ? C'est pas clair du tour n'est-ce pas...

Que renvoie sprintf ? c'est une syntaxe de sprintf que je ne connais pas... normalement ça s'utilise comme ça:

char buffer[20];
sprintf(buffer, "toto=%d", 53);

Lisez avant tout des tutoriaux sur comment fonctionnent les tableaux et pointeurs en langage C, attention ce n'est pas trivial et c'est très important... les tableaux à plusieurs dimensions c'est compliqué. Quand on prend un pointeur dessus c'est encore pire...

casimir_isere:
Je ne comprends pas votre ligne
String (*pTab2D) [x][y] = sprintf("%X", valAdr);

ici, je déclare le pointeur 'pTab2D' sur un tableau de String de taille x,y. 'valAdr' contiens l'adresse (char) du début de mon tableau que je converti en hexa avec 'sprintf %X'.

Je répond à votre question plus bas sur la syntax de sprintf:
Le format X = un entier non-signé en hexadécimal, en lettres majuscules.

casimir_isere:
Vous déclarez un pointeur sur un tableau de x*y objets de type String et vous semblez vouloir y ranger (mais dans quelle case???) le résultat de sprintf...

Je ne comprend pas ce que vous dites ici.

casimir_isere:
Lisez avant tout des tutoriaux sur comment fonctionnent les tableaux et pointeurs en langage C, attention ce n'est pas trivial et c'est très important... les tableaux à plusieurs dimensions c'est compliqué. Quand on prend un pointeur dessus c'est encore pire...

Là est tout le problème, j'ai lu beaucoup de tuto et je ne trouve pas de réponse à ma question. En revanche, il y à quelques post sur des forum qui semble traiter le sujet, mais les réponses sont hasardeuse. Du coup, j'ai l'esprit embrouillé.

C'est pourquoi je suis là.

Je me demande si il est possible de faire 'un tour de passe passe':
Utiliser l'adresse de mon tableau 2D dans ma fonction en l'utilisant comme un tableau 1D puisque finalement, tout est rangé à la suite. Il sufit juste de savoir sur quel ligne on se trouve (grace à la valeur de la variable 'x').

Une capture du moniteur:

Pret...
// ---------------------
Adresse du tableau: 0x21a9
Conversion en dec: 8617
8617

Fonction affichTabPointeur:
Valeur de val: 8617
Valeur de valAdr: 0x21a9

Adresse pointee: 0x21a9
1a9

// ---------------------

Hum, regardez voir si la ligne d'initialisation de pTab2D avec sprintf ne produit pas un gros warning à la compilation. Je ne sais pas ce qu'elle fait mais certainement pas ce que vous pensez... pouvez-vous poster un lien vers la documentation de la fonction sprintf que vous utilisez ? Moi je n'en connais qu'une et le premier paramètre est l'adresse d'une chaine de caractères (char*) où elle doit écrire le résultat, puis en deuxième seulement la chaine "format"...

Ensuite, dites-nous exactement quel est le format du tableau que vous voulez stocker. Je vais vous faire une proposition de code...
S'agit-t-il d'un tableau avec un nombre fixe et connu à l'avance de colonnes, mais le nombre de lignes est inconnu et dépend de ce qu'il y a sur la carte SD ?