Bonjour
Je bute sur un problème peut être bête :
J'ai une liste de prénoms définie comme cela :
char* noms[18];
qui va être remplie en utilisant un formulaire web (ça tournera sur un esp8266)
Je voudrais constituer un message du type :
"L'utilisateur TOTO a sonné"
et le publier via MQTT
J'ai donc le debut et la fin du message qui sont stockés dans un const char :
const char* MESSPARTS[]={"L'utilisateur ", "a sonné"};
J'ai essayé sans succès de former le message global, par exmple avec :
tu te pièges toi même en utilisant une String, dont tu n'as pas besoin. snprintf ( msg, MSG_BUFFER_SIZE, "%s%s%s", MESSPARTS[0], noms[0], MESSPARTS[1]);
devrait faire l'affaire.
En écrivant le message initial, je le suis rendu compte que Serial.print(nom[0]); ne retourne rien dans la boucle principale, alors que ça retourne un prénom dans le setup()
Donc ce n'est même pas un problème de conversion finalement
Il faudrait savoir comment nom[] est rempli. Car char* noms[18]; définit un tableau de pointeurs donc il faut que ces pointeurs pointent soit sur des chaines constantes soit sur des chaines allouées dynamiquement.
tampon2 est une variable locale qui sera détruite lorsque tu sortiras de la boucle for
ne copie pas le contenu. Cette affectation ne fait que placer un pointeur dans le tableau noms. Pointeur qui ne pointera plus sur rien à la fin de la boucle for
Non, puisque tu fais une boucle et qu'à chaque itération de la boucle tu vas changer le contenu de la variable.
Il faut avoir autant de variables distinctes que de places dans ton tableau de nom.
Généralement, pour faire ce genre de chose on fait de l'allocation dynamique. Lorsqu'on ajoute une valeur dans le tableau, on alloue avec malloc une zone mémoire pour stocker le contenu et c'est le pointeur retourné par malloc que l'on place dans le tableau. Sur des CPU avec peu de mémoire comme les cartes Arduino style UNO c'est risqué car on peut vite utiliser toute la mémoire et il n'en reste plus pour faire tourner le programme.
Sinon tu as la possibilité de déclarer un tableau à 2 dimensions pour nom. Par exemple noms[18][12] ce qui permettra de créer 18 noms de 11 caractères. Cela à 2 points faibles:
la taille des noms est donc limitée par la taille déclarée à la création du tableau, dans l'exemple ne noms ne pourront pas faire plus de 11 caractères sinon on va écraser des informations.
on peut gâcher de la mémoire si on a beaucoup de noms courts et peu de noms longs puisqu'on déclare une longueur commune à tous.
Dans le premier cas la mémoire est mieux utilisé mais on risque de consommer toute la mémoire sans s'en apercevoir. Sur des petits CPU cela fonctionne si le nombre de valeurs à créer est réduit et si on ne modifie pas leur contenu dans le programme.
Dans le second cas la mémoire n'est pas utilisée au mieux et on a certaines contraintes mais on sait dès le début (à la compilation) si on va tenir en mémoire.
Par sécurité, il vaut mieux utiliser strncpy(char *dest, const char *src, size_t n) qui évite les débordements si la chaîne à copier est trop longue. strncpy(noms[i-2],tampon2, 10);
Si tu manipules toujours nom et numéro ensemble, tu pourrais créer une structure.
struct fiche{
char nom[11];
int numero;
};
et ensuite tu déclares
fiche fichier[18];
Et tu peux l'utiliser comme ça
struct fiche{
char nom[11];
int numero;
};
fiche fichier[18];
void setup() {
Serial.begin(115200);
// remplissage du fichier
strncpy(fichier[0].nom, "premier nom", 10);
fichier[0].nom[10]=0; // au cas ou la chaine serait trop longue
fichier[0].numero = 12345;
strncpy(fichier[1].nom, "second nom", 10);
fichier[1].nom[10]=0;
fichier[1].numero = 23456;
// lecture du fichier
for(int i = 0; i<2; i++){
Serial.print(fichier[i].nom);
Serial.print(" : ");
Serial.println(fichier[i].numero);
}
}
void loop() {
// put your main code here, to run repeatedly:
}
strtok fait une copie de la chaine de travaille dans la pile, du coup l'espace pointé sera libéré lorsque tu passe à une autre chaine ou à la sortie de la fonction, si tu en utilise une.
Peut être que ton problème venais de là.
Il est possible de se passer de la copie des chaines en utilisant le pointeur sur la chaine conf.values[i] et en remplaçant le caractère '/' par la valeur 0.
Mais cela vaut il vraiment le coup de se prendre la tête si ça marche très bien comme ça