Probleme de char*

Résolu/Fermé
mandrain Messages postés 4 Date d'inscription mardi 12 août 2008 Statut Membre Dernière intervention 17 juin 2014 - 12 juin 2014 à 07:48
mandrain Messages postés 4 Date d'inscription mardi 12 août 2008 Statut Membre Dernière intervention 17 juin 2014 - 13 juin 2014 à 21:37
Bonjour a tous,
je bute sur un petit pb. et je ne vois pas pourquoi j'ai deux longueurs de chaine entre "indice" et "Jvac" dans la fonction suivante:


// verification de dates de conges
void verif_conges()
{
int i;
int max;
// tableau des conges
String conges[]={"25/12","26/12","27/12","28/12","29/12","30/12","31/12","01/01"};
max=(sizeof(conges))/7-1;
char jvac[5] = "";
sprintf(jvac,"%s%u/%s%u",ddate,date,dmois,mois); // la date du jour pour ci-dessous
// verification si c'est un jour de conge
for(i=0 ; i<(max+1)
{
char indice[6];
conges[i].toCharArray(indice,6); // transtypage de conges[i] en char dans indice
Serial.print("jvac=");
Serial.println(jvac);
Serial.print("indice=");
Serial.println(indice);
if(indice==jvac) // c'est un jour de conge
{
travail=false;
break;
}
else
{
travail=true;
}
} // fin du for i
Serial.print("travail");
Serial.println(travail);
Serial.print("date_conges");
Serial.println(date_conges);
} // fin de verif_conges

le nombre de caractères est juste pour "jvac" (5)
le nombre de caractères (6) ne peut pas être réduit pour "indice", ou alors il y en a un spécial devant ? mais rien n'est visible sur la console.
merci de m'aider a comprendre.


2 réponses

[Dal] Messages postés 6174 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 2 février 2024 1 083
Modifié par [Dal] le 13/06/2014 à 11:41
Salut mandrain,

Un développeur C++ te donnera peut être d'autres conseils, mais voilà quelques remarques liées au C, parce qu'il y a beaucoup de problèmes dans ton code liés au mélange que tu fais de C et de C++ et au mauvais usage des parties propres au C.

char jvac[5] = "";
sprintf(jvac,"%s%u/%s%u",ddate,date,dmois,mois);


Je ne sais pas ce qu'il y a dans ddate,date,dmois,mois, mais à supposer que chacun ne nécessite qu'un seul caractère pour son affichage, et pas plus, ta chaîne C "%s%u/%s%u" va nécessiter 5 caractères + le caractère de fin de chaîne '\0', et donc tu auras besoin d'un
char jvac[6]
au moins.

En C, il vaut mieux utiliser snprintf, qui va te permettre de sécuriser cela.

par ailleurs, je ne vois pas d'où viennent ddate,date,dmois,mois, mais moi j'aurai utilisé les entiers avec un spécificateur de taille de sortie et un padding avec un zéro si nécessaire.

Vois cet exemple en C :
#include <stdio.h>

int main(void)
{
    int jour = 1;
    int mois = 1;
    char jvac[6];

    snprintf(jvac, 6, "%02d/%02d", jour, mois);
    printf("jvac = %s\n", jvac);                                                

    return 0;
}


Cela donne à l'écran :
jvac = 01/01
sans autres complications.

Je ne vois pas pourquoi tu fais un tableau de "Strings" C++, si c'est ensuite pour tenter de les convertir en chaînes C. Autant faire directement un tableau de chaînes C.

Ensuite, je ne sais pas ce qu'est ton
conges[i].toCharArray(indice,6);
. Si c'est cela https://docs.microsoft.com/en-us/dotnet/api/system.string.tochararray?redirectedfrom=MSDN&view=netframework-4.8#code-snippet-1 tu l'utilises mal et tu ne convertis rien, puisque tu n'utilises pas la valeur de retour (si tant est que tes paramètres aient un sens).

Ensuite dans la boucle
for(i=0 ; i<(max+1) 
, il n'y a pas d'incrémentation de i... et je ne comprend pas bien comment tu détermines max.

Plus loin, tu fais
if(indice==jvac)
. Comme ce sont deux chaînes C, ce que tu compares ce sont les pointeurs vers les premiers éléments du tableau qui contient ces chaînes, et non pas les chaînes elles-mêmes. Pour comparer deux chaînes C, en C, tu utilises strcmp


Dal
0
[Dal] Messages postés 6174 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 2 février 2024 1 083
13 juin 2014 à 11:47
hmm, à la réflexion, au vu de tes "Serial.print", il y a des chances que tu codes pour Arduino, et que ton String.ToCharArray soit celui-ci :

https://www.arduino.cc/reference/en/language/variables/data-types/string/functions/tochararray/ qui correspond à la syntaxe que tu utilises.


Dal
0
mandrain Messages postés 4 Date d'inscription mardi 12 août 2008 Statut Membre Dernière intervention 17 juin 2014
Modifié par mandrain le 13/06/2014 à 21:39
Effectivement c'est pour Arduino
d'ou un certain nombre de limitation dans les syntaxes admissibles.
par exemple pour "jvac" je n'ai trouvé que cette solution pour formater une date de 5 caractères.
je vais essayer ta méthode pour voir si le compilateur l'admet.
Pour répondre a tes remarques:

"jvac[5]"
la transformation est située plus en amont dans le programme et je vous fait grâce de tous le reste.
char jvac[5] contient : "27/12" exclusivement en 5 caractères
sprintf(jvac),"%s%u/%s%u",ddate,date,dmois,mois);
ces variables contiennent ddate -> un char = "0" ajouté que si la date est a un seul chiffre
date -> un int = 5
dmois-> un char= "0" ajouté que si le mois est a un seul chiffre
mois -> un int = 5
donc le résultat est bien admis par Visual 10 dans la variable "jvac[5]" si la chaine ajoutai un "\O" il faudrait
effectivement un "jvac[6]". Ca n'as pas l'air d'être ça.

"conges[i].toCharArray(indice,6); // transtypage de "conges[i]" en char [5]"
c'est la seule méthode trouvée pour transtyper la chaine.
cette ligne est transformée en:
"conges[i].toCharArray(indice,(2,6)); // transtypage de "conges[i]" en "char[5]"
ce qui limite bien le format de "indice" en "indice[5]" contenant la date genre "27/12"

"for(i=0 ; i<(max+1)"
effectivement lors de la copie pour le message il manquait le i++ pourquoi???

"if(indice==jvac)"
C'est là la question tout le reste tourne, les affichage témoins sont correctes,
seule la comparaison est fausse
je vais essayer strcmp
je n'ai pas réussi a faire cette comparaison.
Il semblerait que "jvac" contient 10 caractères et non 5 comme "indice"
ce n'est pas très compréhensible.
donc j'applique les instructions suivantes pour faire la comparaison:


//for(k=0;k<=4;k++)// avant correction
for(k=0;k<=5;k++)// après correction
{
if(jvac[k] == indice[k])
{
caractere++;
}
else
{
caractere=0;
}
}// fin du for k
if(caractere>=k)
{
travail=false;// jour de conge
Serial.println("c'est un jour de conge");
break;
}
else
{
travail=true;
Serial.println("c'est un jour de travail");
}// fin du if caractere=k

Là ça marche!
maintenant je vais tester le "snprintf" préconisé.
En effet ça marche et la longueur de "jvac" est de [6] et non de [5] maintenant donc correction ci_dessus.

Il me reste ta remarque sur la chaine en C
Pour l'instant je poste ce texte pour faire une mise à jour de notre discution.
Si cela parait long aux lecteurs, je laisse tous les commentaires afin d'aider si c'est util.

Merci pour tes conseils ils m'ont mis sur la bonne voie, la fonction congés tourne.

Bon week end
mandrain
0