Tableau et caractère ascii

bonjour/bonsoir

j'aurais 2 question

première question quel est la différence entre

const word mots[] = {
'pomme',
'poire',
'tomate',
'salade'
};

et

const word mots[] = {
"pomme",
"poire",
"tomate",
"salade"
};

et ma 2eme question
pour le même tableau

const word mots[] = {
'pomme',
'poire',
'tomate',
'salade'
};

par exemple pour le premier 'pomme'
comment on fait comment on fait pour avoir chaque caractère séparément

const word mots[] = {
'pomme',
'poire',
'tomate',
'salade'
};

//je sais pas tros comment expliquer mes en gros mes en gros 

Serial.println(p);
Serial.println(o);
Serial.println(m);
Serial.println(m);
Serial.println(e);

(en vrais c'est pas les lettre sur println que je veux mes sont nombre ascii (A-64, B_65 ...) mes sa je sais faire

en gros avoir une liste de mots et avec une boucle sépare chaque caractère dans un autre tableau

( en espérent que vous avez compris avec les diffèrent exemple par ce que hje sais pas pas comment expliquer je suis pas douer pour développer mon idée :sob:

En gros retenez qu'on utilise les apostrophes pour UN SEUL caractère et les guillemets pour une chaine de caractères

donc si vous avez des mots comme pomme ➜ toujours des guillemets

ensuite le type d'une chaine de caractère c'est const char * pas word (qui représente un entier sur 2 octets)

essayez ce code (tapé ici non testé)

const char* mots[] = {
  "pomme",
  "poire",
  "tomate",
  "salade"
};
const size_t nombreDeMots = sizeof mots / sizeof * mots;

void setup() {
  Serial.begin(115200);
  for (size_t i = 0; i < nombreDeMots; i++) {
    const char * ptr = mots[i];
    while (*ptr != '\0') { // une c-string se termine par un caractère nul
      Serial.println(*ptr);
      ptr++;
    }
    Serial.println("---------");
  }
}

void loop() {}

Ça marche Nikel merci beaucoup mais je peux demander d'avoir un exemple mais sans les pointeurs pour pouvoir comparer (je ne comprends toujours pas les pointeurs (comment ils fonctionnent))

Comme ça

const char* mots[] = {
  "pomme",
  "poire",
  "tomate",
  "salade"
};
const size_t nombreDeMots = sizeof mots / sizeof * mots;

void setup() {
  Serial.begin(115200);
  for (size_t i = 0; i < nombreDeMots; i++) {
    const char * motEnCours = mots[i];
    size_t indice = 0;
    while (motEnCours[indice] != '\0') { // une c-string se termine par un caractère nul
      Serial.println(motEnCours[indice]);
      indice++;
    }
    Serial.println("---------");
  }
}

void loop() {}

Tapé depuis mon iPhone donc non testé

Le tableau initial contient des pointeurs vers les chaînes donc vous n’échapperez pas à la notation avec une étoile même si ensuite on peut utiliser la notation tableau pour accéder aux octets suivants

Sinon il faudrait définir une taille max pour les chaînes et faire un tableau à 2 dimensions pour les stocker.

Par exemple ici on aurait 19 caractères max pour stocker le texte et un caractère réservé pour le caractère nul qui marque la fin de chaîne

 char mots[][20] = {
  "pomme",
  "poire",
  "tomate",
  "salade"
};
const size_t nombreDeMots = sizeof mots / sizeof * mots;

Vous accédez alors aux caractères par un double indice mots[n][i] où n est le Nº du mot (commence à 0) et i le N° du caractère dans ce mot (commence à 0 et ne pas dépasser 19 puisqu’on a 20 cases réservées). Quand on lit les caractères il faut s’arrêter alors quand on rencontre le caractère nul, le contenu des octets suivant ne fait pas partie du mot.

L’inconvénient de cette seconde approche c’est la perte de place mémoire car vous prenez plein de place même si toutes les cases ne sont pas occupées. Ça ne fait du sens que si le contenu du tableau est amené à changer

Essayez de lire et pratiquer avec mon tuto

bonsoir j'ai commencer a lire les pointeur actuellement je fait encor sens pour ce projet le temps de réussir a comprendre
mes j'ai encor besoin d'aide

const char * motEnCours =0 ; 

const char* Mots[]{
   "pomme",
   "poire",
   "tomate",
   "salade",
   "tomme",
   "roblochon"
};

const byte NbtMots = sizeof Mots / sizeof * Mots;


byte lettre [][20]={

};

void setup(){
Serial.begin(9600);
   for (byte NumMots = 0; NumMots < NbtMots; NumMots++) {
      motEnCours = Mots[NumMots];
      byte indice = 0;
      if(motEnCours[indice] != '\0'){
         for(indice; motEnCours[indice]!='\0'; indice++){
            lettre[0][indice] = motEnCours[indice];
            Serial.println((byte)motEnCours[indice]);
         }
      }
   Serial.println("---------");
   }

}

void loop (){
   
      byte X=0;
for(X=0; X!=20; X++){
     Serial.println((char)lettre[0][X]);
      }
 
}

moniteur série

112
111
109
109
101
---------
112
111
105
114
101
---------
116
111
109
97
116
101
---------
115
97
108
97
100
101
---------
116
111
109
109
101
---------
114
111
98
108
111
99
104
111
110
---------
⸮
o
b
l

⸮
h
o
n

la partie nombre cest ce qui marche (nombre= caractère)

et la partie avec les caractère c'est ce qui marche pas

ce que je voulais faire c'étais d'enregistrer chaque caractère (nombre) (donc la dans l'exemple ces 112 111 109 109 101(pomme)

dans un tableau (lettre)

donc sa me sort ni

p
o
m
m
e

mes rien interrecent

⸮
o
b
l

si quelqu'un peux me dire comment faire pour enregistrer chaque caractère individuellement dans un tableau (si possible 2D [mot][caractère]^^ merci avance :slight_smile:

Ca c’était le tableau en 2D

oui ce que je voulais c'étais mon tableau principal

char mots[][20] = {
  "pomme",
  "poire",
  "tomate",
  "salade"
};

et mon second

byte lettre [][20]={

};

qui ce remplie automatiquement avec la partie avent


byte lettre [][20]={
112,111,109,109,101 //pomme
};

et en 2D comme avec

 char mots[][20] = {
  "pomme",
  "poire",
  "tomate",
  "salade"
};

donc

byte lettre [][20]={
{112,111,109,109,101}, //p,o,m,m,e
{112,111,105,114,101}, //p,o,i,r,e
{116,111,109,97,116,101}, //t,o,m,a,t,e
{115,97,108,97,100,101}, //s,a,l,a,d,e
{116,111,109,109,101},//t,o,m,m,e
{114,101,98,108,111,99,104,111,110},//r,e,b,l,o,c,h,o,n
};

Il faut m'expliquer mieux ce que vous cherchez à faire et pourquoi il y aurait besoin de dupliquer la mémoire : les valeurs numériques (codes ASCII) sont déjà en mémoire puisque c'est comme cela que les caractères sont représentés. il suffit de les imprimer comme des entiers au lieu de comme des chars

Testez ceci

const char* mots[] = {
  "pomme",
  "poire",
  "tomate",
  "salade"
};
const size_t nombreDeMots = sizeof mots / sizeof * mots;

void setup() {
  Serial.begin(115200);
  for (size_t i = 0; i < nombreDeMots; i++) {
    const char * motEnCours = mots[i];
    Serial.print("codes ASCII de "); Serial.println(motEnCours);
    size_t indice = 0;
    while (motEnCours[indice] != '\0') { // une c-string se termine par un caractère nul
      Serial.print(motEnCours[indice]); Serial.print(" -> "); Serial.println((byte) motEnCours[indice]);
      indice++;
    }
    Serial.println("---------");
  }
}

void loop() {}

si vous préférez que le tableau soit de type byte (entiers) c'est possible aussi et le compilateur sait faire la conversion (char -> byte ça fonctionne sans souci). ça met quand même le 0 terminal puisqu'on initialiser les pointeurs avec des c-strings. Le parcours restera le même, il faudra juste préciser qu'on veut l'impression sous format caractère quand on veut voir l'ASCII

const byte* mots[] = {
  "pomme",
  "poire",
  "tomate",
  "salade"
};
const size_t nombreDeMots = sizeof mots / sizeof * mots;

void setup() {
  Serial.begin(115200);
  for (size_t i = 0; i < nombreDeMots; i++) {
    const byte * motEnCours = mots[i];
    Serial.print("codes ASCII de "); Serial.println((char*) motEnCours);
    size_t indice = 0;
    while (motEnCours[indice] != '\0') { // une c-string se termine par un caractère nul
      Serial.print((char) motEnCours[indice]); Serial.print(" -> "); Serial.println(motEnCours[indice]);
      indice++;
    }
    Serial.println("---------");
  }
}

void loop() {}

je commence a comprendre comment sa fonctionne mes j'ai encor un problème

 char* Mots[]{
   "pomme",
   "poire",
   "tomate",
   "salade",
   "tomme",
   "reblochon"
}; 


void setup(){

Serial.begin(9600);

Serial.print((char)Mots[0][0]);
Mots[0][0]=109;
Serial.print(":");
Serial.println((char)Mots[0][0]);
}

donc théoriquement le première caractère passe de p à m

mes quand je le fait sa passe de p a p

moniteur

p:p
//a la place de
p:m

j'ai essayer plusieurs chose

Serial.print((char)Mots[0][0]);
Mots[0][0]=97;
Serial.print(":");
Serial.println((char)Mots[0][0]);

celon ce que je met a

Serial.print((char)Mots[0][**0**]);
Mots[0][**0**]=97;
Serial.print(":");
Serial.println((char)Mots[0][**0**]);

la valeur change ou pas pour 0 1 sa reste p et o mes sitot que je passe au dessus de 2 sa marche mes caractère change bien a 'a'

mes aussi quand je fait

byte X=0;
void setup(){
Serial.print((char)Mots[0][X]);
Mots[0][X]=97;
Serial.print(":");
Serial.println((char)Mots[0][X]);
}

et celons la valeur de X que je met sa ne marche pas mémé quand je suis a plus de 2 '

Quand vous faites cela

Votre tableau contient des const char *. En théorie vous n’avez pas le droit de modifier les caractères, sur AVR le compilateur vous laissera faire (avec un warning si vous les activez) mais il refusera sur ESP32.

Si vous voulez modifier le contenu il faut vraiment des tableaux de caractère et donc la version de la déclaration avec un tableau à 2 dimensions


char mots[][10] = {
  "pomme",
  "poire",
  "tomate",
  "salade"
};

Je ne donne pas la première dimension du tableau car le compilateur va la calculer pour moi en fonction de ce que j’utilise pour l’initialisation du tableau. Ici ce sera 4 (c’est un tableau de 4 lignes de 10 colonnes, vous pouvez mettre 9 caractères plus le caractère nul si vous stockez des cStrings dans cet espace mémoire)
Là vous pouvez changer le contenu d’une case par exemple pour faire Tomme au lieu de pomme vous allez écrire le code ascii de T à la place du p donc dans la case à l’index 0,0

mots[0][0]= 'T';

Comme le code ASCII de T est 84, vous pourriez aussi écrire

mots[0][0]= 84;

Ça fait la même chose, mais bien sûr la version avec 'T' est beaucoup plus naturelle et lisible.

sa marche Nikel merci petit question méme si a mon avie c'est impossible

char mots[][10]

y a t'il une possibilité pour qu'il met automatiquement le nombre sur le mots avec le plus de caractère

char mots[][]{
"pomme",
  "poire",
  "tomate",
  "salade",
"reblochon"
};

Ducoup il met le [] [9](par rapport a reblochon 9 caractère 

Non. Le compilateur ne le fait pas. On est obligé de préciser combien on veut d’éléments dans toutes les dimensions sauf la première car la il sait compter le nombre d’éléments dans la liste d’initialisation

Si vous voulez conserver de la mémoire vous pouvez faire un tableau de pointeurs sur des tableaux de caractères

// on déclare chaque cString sous form me de tableau de caractères
// la taille l mémoire réservée varie pour chacun de tableaux
char t1[] = "pomme";
char t2[] =  "poire";
char t3[] = "tomate";
char t4[] =  "salade";
char t5[] = "reblochon";

// on fait un tableau de pointeurs vers ces tableaux
char * mots[] = {t1, t2, t3, t4, t5};

La encore vous pouvez changer le contenu d’une case par exemple pour faire Tomme au lieu de pomme vous allez écrire le code ascii de T à la place du p et comme on peut utiliser la notation des tableaux avec les crochets avec des pointeurs, on peut encore écrire

mots[0][0]= 'T'; // mots[0] est un pointeur

Mais attention chaque ligne n’a pas la même taille.

1 Like

cest ce que je voulais savoir merci beaucoup pour ton aide J-M-L :slightly_smiling_face:

Bons bricolages

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.