Bienvenue aux nouveaux arrivants sur FantasPic !

- Pensez à lire les règles durant votre visite, il n'y en a pas beaucoup, mais encore faut-il les respecter .
- N’hésitez pas à faire des remarques et/ou suggestions sur le Forum, dans le but de l'améliorer et de rendre vos prochaines visites plus agréables.
- Vous pouvez regarder votre "panneau de l'utilisateur" afin de configurer vos préférences.
- Un passage par "l'utilisation du forum" est recommandé pour connaître les fonctionnalités du forum.

--- L’équipe FantasPic ---
Forum général sur le langage C !

Modérateur : Jérémy

table de char et string , une affaire de null
paulfjujo
Avatar de l’utilisateur
Expert
Expert
Messages : 1836
Âge : 70
Enregistré en : juillet 2015
Localisation : 01800
Contact :

#1 Message par paulfjujo » jeu. 11 févr. 2021 15:41

bonjour,

Je m'aperçois à nouveau ,que coté MikroE ( MikroC) , on n'est pas rigoureux
dans l'usage des tables contenant des caracteres ou bytes ,et la notion de string = chaine de caracteres terminée par un zero.
Sujet à erreur qui peut envoyer le programme dans le décor ..

Exemple avec l'usage , peu usité, mais performent de la fonction strtok (appartenant à la librairie MikroC C_String )
dont le but est d'extraire des morceaux d'une chaine de valeurs ascii ,séparés par un caractere specifique ..
souvent la virgule ( Aux USA) ou le point virgule (en Europe) ... pour se differencier du point decimal americain lorsque les variables
representent des nombres decimaux.
S'applique particulierement sous excel , et le format CSV .

voir la version originale sur le forum MikroC " How do I split a string, by delimiter character?"

Le but est de séparer les champs d'une chaine de caracteres , format CSV ( separateur =';')
et la question portait sur l'init de la table de reception pouvant contenir jusqu'à 32 strings de 16 chars
si on dimensionne la table
char destination_strings[32][16];
et que dans le cas le plus defavorable on recupere 32 strings de 16 chars , on deborde d'un byte à chaque string rajouté
vu qu'il manque la place pour mettre le zero terminator
Le probleme n'est visible que si on relit la table en question ...
Le probleme peut passer inaperçu ou planter le MCU , par debordement emplacement RAM ..

bout de programme pour mettre ceci en evidence
dans les 2 cas de figure. (on ne voit aucun problem dans le 1er test , vu qu'il n'y a qu'une seule variable sur 16 chars)

Code : Tout sélectionner



char string
[80] = "Michael;Jackson;Elton;John;Paulfjujo;Artemis;1234567890123456;fin;testOK;";   //74 chars
char *token;
char destination_strings[32][16];
char MaxStringOf16chars[80] = "1234567890123456;1234567890123456;1234567890123456;";

..
 main ...

  UART1_Write_CText("\r\n Test strtok sur : \r\n");
  UART1_Write_Text(string);
  CRLF1();token = strtok(string, ";"); CRLF1();
  for (i=0;i<8;i++) Suite[i]=i+48;
  i=0;
  while( token != 0 ) {
    strcpy(destination_strings[i], token );
    UART1_Write_Text( destination_strings[i]); CRLF1();
    i++;
    token = strtok(0, ";");
  }
  UART1_Write_CText("\r\n Restitution des strings : \r\n");
  for (i=0;i<9;i++)
  {
  UART1_Write_Text( destination_strings[i]);
  CRLF1();
  }
  
  
//======== Test avec XX  16 ou 17 cars pour table  destination_strings[32][xx]; ====
  
  UART1_Write_CText
("\r\n Test strtok sur : \r\n");
  UART1_Write_Text(MaxStringOf16chars);  CRLF1();
  CRLF1();
  token = strtok(MaxStringOf16chars, ";");
  i=0;
  while( token != 0 ) {
    strcpy(destination_strings[i], token );
   UART1_Write_Text( destination_strings[i]); CRLF1();
    i++;
    token = strtok(0, ";");
  }

  UART1_Write_CText("\r\n Verification , Restitution des strings stockés : \r\n");
  for (i=0;i<3;i++)
  {
  UART1_Write_Text( destination_strings[i]);
  CRLF1();
  }
 


resultats


char destination_strings[32][16];

Test strtok sur :
1234567890123456;1234567890123456;1234567890123456;
// during string extraction
1234567890123456
1234567890123456
1234567890123456
// corrupted on verification!!!
Verification , Restitution des strings stockés :
123456789012345612345678901234561234567890123456
12345678901234561234567890123456
1234567890123456

==========================================
with char destination_strings[32][17];
=========================================
Test strtok sur :
1234567890123456;1234567890123456;1234567890123456;
// during string extraction
1234567890123456
1234567890123456
1234567890123456
// OK on verification
Verification , Restitution des strings stockés :
1234567890123456
1234567890123456
1234567890123456



oops c'est juste pour faire progresser le smilblick !,
il y a tellement de pièges à eviter

Rappel et autres methodes
Aides toi, le ciel ou FantasPic t'aideras

Retourner vers « Langage C »

Qui est en ligne

Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 4 invités