Comment ne pas utiliser String?

Bonjour, suite aux suggestions de certains membres de ce forum, je travaille présentement à ré-écrire du code que j'avais déjà fait afin de ne plus utiliser de "String"..

Je suis débutant en Arduino, donc je m'excuse si mes questions sont un peu "basique"...

Donc voici:

Question #1: Dans mon code j'ai ceci:
char inChar[0];
[...]
inchar=Serial1.read();
if (inchar=='+'){

Si je comprend bien, mon "+" est du string? Donc est-ce mieux de comparer de cette façon?:
if (inchar==(char)43){

Ou peut-être il existe des façon mieux de faire ma comparaison?

Question#2
De temps à autre je veut afficher dans mon moniteur série ce que le programme fait, présentement dans mon code j'ai:

Serial.println("Demarrage du programme...");

Si je veut ne pas utiliser de string, comment dois-je faire pour envoyer la même chose? Si je fait ceci est-ce correct?
Serial.print((char)68);
Serial.print((char)101);
Serial.print((char)109);
Serial.print((char)109);
ETC...

Ya t'il des façons plus efficace d'envoyer des données sur mon port série sans utiliser de string?

Comme je dit plus haut, je sais que mes questions peuvent paraitre bizarre, mais je suis débutant..

Salut,

Ce qu'on a dû te dire c'est de ne pas utiliser la classe String, pas les string qui sont des tableaux de char.

String : String() - Arduino Reference
string : string - Arduino Reference

Ok, tu as raison les gens parlent de "classe String", mais comme je ne m'y connais beaucoup je me suis mal exprimé dans ma question..

Mais malgré tout mes questions sont toujours les mêmes, comment ne pas utiliser la "classe String"?

Ou en gros, quand j'écrit:

if (inchar=='+'){

ou

Serial.println("Demarrage du programme...");

Est-ce que c'est correct? ou est-ce que cela utilise la classe string? Dois-je les convertir ou pas? Si oui comment?

Oui je sais que je part de loin et que je ne comprend pas vraiment la différence entre "string et classe String", j'ai regardé les deux liens plus haut mais je ne comprend pas plus la différence... Peut-être quelqu'un peut m'expliquer d'une façon simple?

1/ tu n'utilises toujours pas les balises code.

KingRamses:
Donc voici:

Question #1: Dans mon code j'ai ceci:
char inChar[0];
[...]
inchar=Serial1.read();
if (inchar=='+'){

Si je comprend bien, mon "+" est du string? Donc est-ce mieux de comparer de cette façon?:
if (inchar==(char)43){

Ou peut-être il existe des façon mieux de faire ma comparaison?

  • inChar[0] zéro pour une chaine ? c'est pas possible. il faut utiliser char inChar[nombredecaractères]
    Attention, il faut ajouter 1 au nombre maximal de caractère qu'il pourra y avoir dedans.

  • non, le + comme tu l'utilises n'a rien a voir avec C++ ou la Classe String. C'est le fait de faire par exemple toto += "!"

  • ta comparaison est bonne si on compare un char (1 caractère) Bien que ton (char) qu'on appelle un Cast, ne soit pas utile.
    Il est possible aussi de faire if(inchar=='A')..., (avec des simples cotes) ainsi, pas besoin de connaître la valeur ASCII de "A"
    En C, si tu veux comparer une chaine, il faut utiliser la fonction strcmp.
    Donc if(maChaine == "Toto") est interdit !

Question#2
De temps à autre je veut afficher dans mon moniteur série ce que le programme fait, présentement dans mon code j'ai:

Serial.println("Demarrage du programme...");

Tu ne changes absolument rien.

Ya t'il des façons plus efficace d'envoyer des données sur mon port série sans utiliser de string?

Comme je dit plus haut, je sais que mes questions peuvent paraître bizarre, mais je suis débutant..

Pour écrire sur le port série Serial.print ou Serial.println comme tu l'as toujours fait. Ce qui change c'est le traitement (la manipulation des chaines) avant l'affichage.
La plupart du temps, ça se reconnait à des facilités à comparer/concaténer/convertir/extraire des chaines les unes aux autres.

Les problèmes que tu rencontrent sont évidement normaux (lorsqu'on débute dans ces langages, tout le monde y passe). D'autant plus que Arduino fait un mix de C et C++. Ta réaction me confirme qu'il n'est pas bon de débuter en mélangeant ces 2 langages (débat eu avec pepe la semaine dernière), quelque soit leurs similitudes ou origines.

Maintenant, il est évident qu'il va être difficile de progressser sans apprendre vraiment le C (surtout lorsqu'on bosse sur des µC). Je te conseille vivement d'attaquer un tutoriel sur ce langage, et de voir les bases (variables, opérations, structures conditionnelles, pointeurs, modularité)

vohu:

  • inChar[0] zéro pour une chaine ? c'est pas possible. il faut utiliser char inChar[nombredecaractères]
    Attention, il faut ajouter 1 au nombre maximal de caractère qu'il pourra y avoir dedans.

Merci beaucoup pour ton aide!

C'est ptete pas possible d'écrire "inChar[0];" mais pourtant ça fonctionne :slight_smile: Mais bon, si je comprend bien ce que tu m'as expliqué: la ligne serial.read lis un caractère à la fois, donc le nombre après "inChar" dois être 2 (1 caractère lus + un caractère de plus)

Le reste de mon code est bon donc je ne change rien?

Exemple:

    char inChar[2];
    [...]
    inchar=Serial1.read();
    if (inchar=='+'){

Tu me dit que ma comparaison est bonne, et aussi que je peut utiliser "strcmp" ? Suis-je mieux d'utiliser strcmp plutot que ma comparaison actuelle? Quelle est l'avantage d'utiliser strcmp au lieu de ma comparaison?

Les problèmes que tu rencontrent sont évidement normaux (lorsqu'on débute dans ces langages, tout le monde y passe). D'autant plus que Arduino fait un mix de C et C++. Ta réaction me confirme qu'il n'est pas bon de débuter en mélangeant ces 2 langages (débat eu avec pepe la semaine dernière), quelque soit leurs similitudes ou origines.

Je sais que ça ne parait pas, mais j'ai programmé en Delphi pendant des années, je connais plusieurs autres langages, mais le C, c'est tout nouveau pour moi...

Me semble que j'ai déjà lus quelque part qu'il est possible de programmer l'arduino en assembleur, est-ce vrais? (j'ai du apprendre l'assembleur 6502 ily a plusieurs année quand on programmais des ordis commodore) Je n'ai pas vraiment envie de me remettre à l'assembleur, car je vais perdre un après midi pour écrire une routine qui prend 5 minutes à faire en c.. Mais je me posai seulement la question à savoir si c'étai possible??

char xxx[0] fonctionne sans doute, mais c'est par chance. Voir ce qu'est un dépassement de tampon en C; qui arrive le plus souvent sur les chaines de caractères justement.

  • Pour une seule lettre on fait : char malettre = '+';
    La simple cote rempalce le caractère par son code ASCII, mais humainement, c'est plus pratique

  • On pourrait faire aussi char malettre[2] = "+" (note les doubles cotes ici, contrairement à au dessus)
    On fait donc 1 tableau de 2 char. On pourrait l'écrire ainsi : char malettre[2] = { 43, 0 }, ou char malettre[2] = { '+', '\0' } ou encore char malettre[2] = { 0x2b, 0x00 };
    C'est à cause de ce '\0' qu'on doit ajouter 1 à la taille du tableau. Et c'est lui qui permet de savoir que la fin de la chaine est atteinte.
    Concernant le char malettre[1] = "+" J Il ne permet pas de définir cette fin de chaine, c'est pour ça qu'il pourrait provoquer un dépassement de tampon
    Les chaines de caractères sont très liées aux pointeurs, comprendre un peu les pointeurs, permet de comprendre la raison de certaines façon de faire en C qui ne semblent pas logiques au premier abord. Surtout lorsqu'on vient d'un langage haut niveau (Perso, je suis arrivé du visual basic 6 :D)

  char inChar[2];
    [...]
    inchar=Serial1.read();
    if (inchar=='+'){

Le if ne fonctionne justement pas n'est pas bon. Car tu compares une chaine à un caractère. Il est possible que ce code fonctionne aussi, mais du coup, il ne comparera que le premier caractère de la chaine avec ton caractère

Oui, on peut programmer les AVR en assembleur. Je crois même qu'a partir du langage C on fait
asm("code assembleur");

vohu:
Le if ne fonctionne justement pas n'est pas bon. Car tu compares une chaine à un caractère. Il est possible que ce code fonctionne aussi, mais du coup, il ne comparera que le premier caractère de la chaine avec ton caractère

Merci beaucoup de ton aide, tu dit que le if n'est pas bon? Au moins j'ai deux lignes de bonne sur 3! :slight_smile: Pourrais-tu me donner un exemple de comment je pourrais ré-écrire le "if" pour qu'il soit bon?

Ou en gros, comment écrirais-tu ce code pour qu'il soit bon?

  char inChar[2];
    [...]
    inchar=Serial1.read();
    if (inchar=='+'){

Merci encore!

Attention à ne pas confondre char et tableau de char.

'+' => char
"+" => string (ajout automatique d'un caractère null en fin de chaine)

inChar[0] est valide, en fait c'est équivalent à un pointeur de char => char *inChar;

Le caractère null est indispensable en fin de chaine, car toute les fonctions utilisant les string en argument utilise ce caractère pour détecter la fin d'une chaine. Quand on déclare une chaine, il faut mieux l'initialiser comme ceci :

char maChaine = "Arduino";

équivalent à

char maChaine[] = {'A','r','d','u','i','n,'o',NULL);

ou encore

char maChaine[8];
maChaine[0]='A';
maChaine[1]='r';
maChaine[2]='d';
maChaine[3]='u';
maChaine[4]='i';
maChaine[5]='n';
maChaine[6]='o';
maChaine[7]='\0'; // autre écriture de NULL

KingRamses:
Merci beaucoup de ton aide, tu dit que le if n'est pas bon? Au moins j'ai deux lignes de bonne sur 3! :slight_smile: Pourrais-tu me donner un exemple de comment je pourrais ré-écrire le "if" pour qu'il soit bon?

Ou en gros, comment écrirais-tu ce code pour qu'il soit bon?

  char inChar[2];

[...]
    inchar=Serial1.read();
    if (inchar=='+'){

Y a plein de façon de faire, mais dès le moment que c'est une chaine (donc un tableau dont la déclaration est faite avec []), le plus simple est d'utiliser strcmp, comme expliqué plus haut.

Va lire ça et poste le résultat après

Va lire ça et poste le résultat après

Merci de ton aide, j'ai lus la page et j'ai essayé de faire un strcmp mais j'arrive à rien, j'ai essayé pendant plus d'un heure avec différentes façon et j'ai toujours des erreurs de compilation...

J'suis vraiment pas très bon.. j'arrive à rien..

Voici un exemple de ce que j'ai essayé:

char inchar; // Contient le caractère reçu du module GSM

void loop()
{
    char signeplus[2];
    signeplus[1]='+';
    signeplus[2]='\0';
    
  if(Serial1.available() >0)
  {
    inchar=Serial1.read();
    int resultat = 0;
    resultat = strcmp(inchar,signeplus);
      if (resultat == 0){
      Serial.println("ok");
      }
  }
}

Non mais ce que tu avais avant était bon, je vois pas pourquoi tu t'obstines avec tes chaines ...

 if(Serial1.available() >0)
  {
    
    inchar=Serial1.read();
    
 if (inchar == '+'){
      Serial.println("ok");
      }
}

Auquel cas tu veux faire de trucs pour rien, ceci fonctionnerait :

void loop()
{
    char signeplus[2];
    signeplus[1]='+';
    signeplus[2]='\0';
    
  if(Serial1.available() >0)
  {
char inchar[2];
    inchar[0]=Serial1.read();
    inchar[1]=NULL;
    int resultat = 0;
    resultat = strcmp(inchar,signeplus);
      if (resultat == 0){
      Serial.println("ok");
      }
  }
}

grillé par Batto.

Aussi, tu peux rempalcer :

   char signeplus[2];
    signeplus[1]='+';
    signeplus[2]='\0';

par

   char signeplus[2] = "+";

Mais faut que tu apprennes le C maintenant. Car on aura beau t'expliquer les chaines, si tu comprends pas la base du C, tu comprendras pas nos exemples. On peut pas s'amuser à t'expliquer tout dans le moindre detail alors qu'il existe des tas de cours pour ça

Non mais ce que tu avais avant était bon, je vois pas pourquoi tu t'obstines avec tes chaines ...

En fait je ne m'obstine pas, c'est que vohu m'as dit ceci:

dès le moment que c'est une chaine (donc un tableau dont la déclaration est faite avec []), le plus simple est d'utiliser strcmp, comme expliqué plus haut.

Je croyais donc que d'utiliser "if (inchar=='+'){" n'étai pas une bonne façon de faire et que je devais utiliser des strcmp.

Mais si vous me dite que mes comparaison"if (inchar=='+'){" peuvent être utilisé tel-quel sans problèmes, et bien j'me casserai pas la tête pour faire d'autre chose..

Je m'excuse, je vous avais mal compris...

NON !

Tu confonds tout.

Voir post N°4

A cette question j'ai répondu : NON

Tu as dit :

Question #1: Dans mon code j'ai ceci:
char inChar[0];
[...]
inchar=Serial1.read();
if (inchar=='+'){

Si je comprend bien, mon "+" est du string? Donc est-ce mieux de comparer de cette façon?:
if (inchar==(char)43){

Ou peut-être il existe des façon mieux de faire ma comparaison?

J'ai répondu :

...

  • non, le + comme tu l'utilises n'a rien a voir avec C++ ou la Classe String. C'est le fait de faire par exemple toto += "!"

  • ta comparaison est bonne si on compare un char (1 caractère) Bien que ton (char) qu'on appelle un Cast, ne soit pas utile.
    Il est possible aussi de faire if(inchar=='A')..., (avec des simples cotes) ainsi, pas besoin de connaître la valeur ASCII de "A"
    ...

Je viens de comprendre un truc. Tu crois que tout le monde t'as conseillé dans l'autre post de ne plus utiliser de string. On t'a dit d'éviter d'utiliser la CLASSE String. Pas de ne pas utiliser des chaines de caractères, qu'on appelle "string" même en C.

Utiliser la classe String, c'est déclarer des variables comme ça :

String mavariable;
mavariable.substring(....);
mavariable.trucmuche(...,...);

Sans la classe String ou en C, ça donne :

char *mavariable;
char *mavariable = "Salut";
ou
char mavariable[];
char mavariable[100] = "test";

Enfin bref, y a des tas de façon de faire.

Il faut que tu suives un tuto langage C ! on pourra pas grand chose de plus tant que tu n'auras pas les bases

C'est super! Alors je n'ai pas besoin de tout re-changer mes comparaisons!

À la base, ce qui n'est pas clair pour moi, c'est qu'on me dit de ne pas utiliser la "classe string" mais je ne comprend pas bien ce qu'est la "classe string"

Quand je lis ce lien: String() - Arduino Reference

on me donne une liste:
StringConstructors
StringAdditionOperator
StringIndexOf
StringAppendOperator
StringLengthTrim
StringCaseChanges
StringReplace
StringRemove
StringCharacters
StringStartsWithEndsWith
StringComparisonOperators
StringSubstring

Si je comprend bien je dois essayer d'éviter d'utiliser ce qui est dans cette liste?

exemple:

mastring.substring(3,5) ne dois pas être utilisé?

Ais-je bien compris?

Ouiiiiiii ! Haaaaaaa ???

Je ne retire cependant pas ce que j'ai écrit en rouge avant

Je viens de comprendre un truc. Tu crois que tout le monde t'as conseillé dans l'autre post de ne plus utiliser de string. On t'a dit d'éviter d'utiliser la CLASSE String. Pas de ne pas utiliser des chaines de caractères, qu'on appelle "string" même en C.

Utiliser la classe String, c'est déclarer des variables comme ça :

String mavariable;

mavariable.substring(....);
mavariable.trucmuche(...,...);

Ha!! la c' est clair!!
Je crois que tu viens de me faire comprendre! :slight_smile:

Quand j'écrit le nom de ma string suivi d'un point suivi d'autre chose c'est la classe string et ce n'est pas recommandé..

Super!

Ya t'il d'autre chose concretement que je dois essayer de ne pas utiliser? ou si c'est juste ce que tu m'as dit?