quelqu'un peut m'eclairer sur les char et string ?

Bonjour, voici mon programme simple et qui fonctionne !
pourtant le compilateur m'affiche un warning ...
j'ai lu sur le forum que l'utilisation de String menait droit au probleme de mémoire,
auriez vous une solution à m'apporter pour m'affranchir de ce problème

voici mon code

#include <SPI.h>
#include <RFID.h>

RFID RFID(10,9);

int UID[5];
String myKey; 
char *myStrings[] = {"158.89.145.185.2.", "0.238.120.163.5.", "155.153.9.43.3." };
char *proprio[] = {"Papa", "Maman", "Maxence" };
bool inconnu;
void setup()
{
  Serial.begin(9600);
  SPI.begin();
  RFID.init(); 
}

void loop()
{
   
    if (RFID.isCard()) {  
          if (RFID.readCardSerial()) {        
            for(int i=0;i<=4;i++)
            {
              UID[i]=RFID.serNum[i]; // je lis une valeur numérique 0 à 255
               myKey=myKey + String (UID[i],DEC) + "."; // je la copie dans la variable myKey au format texte
            }
            Serial.println("");
          }          
          RFID.halt();
    }
    delay(100);   // en sortie de boucle j'ai un format xx.xx.xx.xx.xx.

if (myKey!="") {
Serial.println(myKey);
inconnu = true;
for (int i = 0; i < 6; i++) {
   if (myKey == myStrings[i]) {   // je compare via un tableau si la valeur obtenue correspond aux valeurs enregistrées
     Serial.print("carte connue :");
     Serial.println(proprio[i]);
     inconnu = false;
   }
    
   }

if (inconnu == true ){
  Serial.println("Carte non autorisée.");
}
 
}
myKey="";
delay(1000);
}

voici maintenant ce que me dit le compilateur ! lol il se dechaine sur mon programme

C:\Users\D\Desktop\rfidoktest\rfidoktest.ino:8:85: warning: ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings]

char *myStrings[] = {"158.89.145.185.239.", "0.238.120.163.53.", "155.153.9.43.32." };

^

C:\Users\D\Desktop\rfidoktest\rfidoktest.ino:8:85: warning: ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings]

C:\Users\D\Desktop\rfidoktest\rfidoktest.ino:8:85: warning: ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings]

C:\Users\D\Desktop\rfidoktest\rfidoktest.ino:9:47: warning: ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings]

char *proprio[] = {"Papa", "Maman", "Maxence" };

^

C:\Users\D\Desktop\rfidoktest\rfidoktest.ino:9:47: warning: ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings]

C:\Users\D\Desktop\rfidoktest\rfidoktest.ino:9:47: warning: ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings]

C:\Users\D\Desktop\rfidoktest\rfidoktest.ino: In function 'loop':

C:\Users\D\Desktop\rfidoktest\rfidoktest.ino:42:28: warning: iteration 3 invokes undefined behavior [-Waggressive-loop-optimizations]

if (myKey == myStrings*) {*

  • ^*
    C:\Users\D\Desktop\rfidoktest\rfidoktest.ino:41:19: note: containing loop
    for (int i = 0; i < 6; i++) {
  • ^*
    C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino\main.cpp: In function 'main':
    C:\Users\D\Desktop\rfidoktest\rfidoktest.ino:42:28: warning: iteration 3 invokes undefined behavior [-Waggressive-loop-optimizations]
    _ if (myKey == myStrings*) {_
    _
    ^_
    C:\Users\D\Desktop\rfidoktest\rfidoktest.ino:41:19: note: containing loop
    for (int i = 0; i < 6; i++) {
    _
    ^_
    Le croquis utilise 5112 octets (15%) de l'espace de stockage de programmes. Le maximum est de 32256 octets.
    Les variables globales utilisent 342 octets (16%) de mémoire dynamique, ce qui laisse 1706 octets pour les variables locales. Le maximum est de 2048 octets.
    _
    :o*_
    Mais le plus beau dans l'histoire....c'est que ça fonctionne !!! 8) ;D

Déjà, myStings et proprio peuvent être déclarés en const:

 char *myStrings[] = {"158.89.145.185.2.", "0.238.120.163.5.", "155.153.9.43.3." };


// devient
const  char *myStrings[] = {"158.89.145.185.2.", "0.238.120.163.5.", "155.153.9.43.3." };

(permet d'éviter tous les deprecated conversion from string constant to ‘char* -le message d'erreur des versions precedentes de g++- ou, me semble-t-il, votre message d'erreur concernant la conversion, avec une version plus récente de g++.

Ensuite, myKey n'est pas initialisé; je pense qu'il est de longueur maximale 21 et j'en fais un char[21]

char myKey [21]; // (longueurmax champ : 4) *5 + null terminator
// le remplissage avec une boucle de myKey devient (en deroulant la boucle : c'est lourd)
[code]
  char myKey[21];
   sprintf(myKey, "%d.%d.%d.%d.%d\0", UID[0], UID[1], UID[2], UID[3], UID[4]); 
   printf("myKey,%s\n", myKey); // test sur PC avec g++

Notez que je n'ai pas regardé l'égalité pour le moment;
sur PC, le bout de code

  for (int i=0;i<3;i++) {
     printf("%s\n", myStrings[i]);
      printf("cmp %d \n", strcmp(  myStrings[i] ,  myKey) );
}

confirme que strcmp retourne une valeur positive en cas d'égalité (négative si les 2 chaines ne sont pas égales)

Je crois que je vous ai oté quelques Strings (contestés à cause des fuites mémoire); J'ai pu le tester sur PC (mais les compilateurs sont de la même famille)
:
sprintf(myKey ,

strcmp() retourne 0 en cas d’égalité (négatif ou positif si alphabétiquement avant ou après)

Il n’y a aucune raison de transformer des nombres en ASCII pour faire des comparaisons.... mKey ne sert à rien, comparez directement un tableau d’octet avec le tableau RFID.serNum en utilisant memcmp() vous gagnerez bcp de place

Tu pourrais aussi supprimer tous les String.
La clé est composée de nombres

UID[i]=RFID.serNum[i]; // je lis une valeur numérique 0 à 255

donc je ne vois pas du tout l'intérêt de convertir ces nombres en chaînes et ensuite de comparer des chaînes alors que localement tu pourrais stocker les chaînes autorisées sous forme d'un tableau de nombre à 2 dimensions et tu pourrais comparer directement les clés. Tu éviterais ainsi les String de mauvaise réputation.
[EDIT]: grillé

@fdufnews - dsl j’éditais mon post pour mettre l’url sur memcmp() on a posté en même temps :slight_smile:

Ah bah ... oui effectivement... je vais tenter le coup ;).

merci je reviens vers vous si jamais je galere !

Pour les références sous forme de tableau de chiffres, au lieu de const  char *myStrings[] = {"158.89.145.185.2.", "0.238.120.163.5.", "155.153.9.43.3." };va falloir utiliser

const byte mesCartes[][5] = {
  {158, 89, 145, 185, 2}, 
  {0,238,120,163,5},
  {155,153,9,43,3}
};
const byte nombreDeCartesConnues = sizeof(mesCartes)/sizeof(mesCartes[0]); // le compilateur calculera pour vous le nombre de cartes déclarées, utile pour écrire la boucle de comparaison

et mesCartes[index] ce sera un tableau à comparer sur une longueur de 5 octets avec le tableau du N° de série

Ca fonctionne nickel !!! j'ai utilisé le tableau avec entrées multiples ! ca roule nickel

merci pour tout

bravo :slight_smile: