Utilisation de strcmp
Dernière réponse : dans Programmation
Bonjours tout le monde
j'ai une fonction main ou je fais appel à la fonction strcmp, mais à la compilation j'ai ce warning qui s'affiche :
warning: passing argument 2 of 'strcmp' makes pointer from integer without a cast
et voici mon code :
Ce que je veux faire, c'est de comparais si la ligne que j'ai stoqué dans mon bufferISR sur la quel je me trouve est égal à la chaine de fin de fichier qui est ':00000001FF'.
Je vous remercie d'avance de l'attention que vous porterez à mon problème!!!
j'ai une fonction main ou je fais appel à la fonction strcmp, mais à la compilation j'ai ce warning qui s'affiche :
Citation :
warning: passing argument 1 of 'strcmp' makes pointer from integer without a castwarning: passing argument 2 of 'strcmp' makes pointer from integer without a cast
et voici mon code :
if(strcmp(bufferISR[index_ligne][0],':00000001FF')==0)
Ce que je veux faire, c'est de comparais si la ligne que j'ai stoqué dans mon bufferISR sur la quel je me trouve est égal à la chaine de fin de fichier qui est ':00000001FF'.
Je vous remercie d'avance de l'attention que vous porterez à mon problème!!!
Autres pages sur : utilisation strcmp
Lassé par la pub ? Créez un compte
Bon, c'est visiblement toujours pour un micro-controleur.
Alors en plus du post de mcpherson, j'ajoute:
- Le premier paramètre est la chaine de caractère c'est-à-dire un pointeur sur le premier caractère : bufferISR[index_ligne] tout court.
- Autre détail d'importance, strcmp compare des chaines, donc doivent être terminées par un '\0', ce qui est le cas implicite de (char*)":00000001FF". Si jamais tu ne veux comparer d'un nombre précis de caractère sans se soucier de la fin de chaine, utilise plutôt memcmp(). Je pense que c'est ton cas.
Alors en plus du post de mcpherson, j'ajoute:
- Le premier paramètre est la chaine de caractère c'est-à-dire un pointeur sur le premier caractère : bufferISR[index_ligne] tout court.
- Autre détail d'importance, strcmp compare des chaines, donc doivent être terminées par un '\0', ce qui est le cas implicite de (char*)":00000001FF". Si jamais tu ne veux comparer d'un nombre précis de caractère sans se soucier de la fin de chaine, utilise plutôt memcmp(). Je pense que c'est ton cas.
Merci pour vos réponse mais cela ne fonctionne toujours pas
Voici la ligne qui me pose problème dans mon main :
j'ai un gros soucie parceque à cause de cette ligne je n'arrive pas a rentré dans ma section de bootloader.
et lorsque j'enlève la partie du strcmp j'arrive a y entrée
voila comment je déclare mon bufferISR :
au début je l'avait en volatile pour pouvoir modifier les données de nbr_lignes et car mais cela ne fonctionné pas =s
Je ne comprend pas pourquoi cela bloque à cette ligne
Voici la ligne qui me pose problème dans mon main :
if((index_ligne >= 16) || (strcmp(bufferISR[index_ligne],":00000001FF") == 0))
j'ai un gros soucie parceque à cause de cette ligne je n'arrive pas a rentré dans ma section de bootloader.
et lorsque j'enlève la partie du strcmp j'arrive a y entrée
voila comment je déclare mon bufferISR :
#define CAR 45
#define NBR_LIGNES 16
char bufferISR[NBR_LIGNES][CAR];
au début je l'avait en volatile pour pouvoir modifier les données de nbr_lignes et car mais cela ne fonctionné pas =s
Je ne comprend pas pourquoi cela bloque à cette ligne
Comme la fait remarqué CRicky il serait peut être préférable d'examiner ça avec un memcmp() !
Je ne garantis rien, fais longtemps que je n'ai pas fait de C ...
const char* EndOfFile = ":00000001FF";
int n;
...
len1 = strlen(bufferISR[index_ligne]);
len2 = strlen(EndOfFile );
n = memcmp ( bufferISR[index_ligne], EndOfFile , len1>len2?len1:len2 );
if( (index_ligne >= 16) || (n == 0) )
Je ne garantis rien, fais longtemps que je n'ai pas fait de C ...
Merci Redtux et Cricky pour vos aide, mais je commence à perdre espoir
cela fait maintenant 1semaine que je cherche mon problème mais sans réussite.
A chaque fois que je rajoute la ligne du strcmp ou du memcmp cela fait tout planter, et je n'arrive même plus rentrer dans ma section de bootloader.
Mais bon éssayon de reprendre depuis le début, je suis sur que c'est une érreur d'appel de mon tableau a double dimention :
voici mes variable global :
Voici ma fonction ISR ou je récupère les données arrivant par la liaison RS232 :
J'ai même réécrie mes propres fonction strlen et strcmp :
longueur_chaine = strlen
comparer_chaine = strcmp
et maintenant voici mon programme main (ou j'ai comme vous pouvez le constater tester ce que Redtux ma proposé):
Ce que je trouve bizarre, c'est que quand je fait un strcmp ou un memcmp (ou avec mes fonction longueur_chaine...) mon programme ne rentre même plus dans le while(1), les 4LEds de s'allume même plus, mais quand j'enlève, cela refonctionne normalement...
Je pensse que l'erreur vient de mon bufferISR[index_ligne] mais ou précisement?!
Voyer vous quelques chose qui cloche? en tout cas mon compilo n'indique aucune erreur ou warning .
cela fait maintenant 1semaine que je cherche mon problème mais sans réussite.
A chaque fois que je rajoute la ligne du strcmp ou du memcmp cela fait tout planter, et je n'arrive même plus rentrer dans ma section de bootloader.
Mais bon éssayon de reprendre depuis le début, je suis sur que c'est une érreur d'appel de mon tableau a double dimention :
voici mes variable global :
/************ Variables Globales **************/
volatile int index_ligne;
volatile int index_caractere;
char bufferISR[NBR_LIGNES+1][CAR];
/*******************************************/
Voici ma fonction ISR ou je récupère les données arrivant par la liaison RS232 :
ISR( USART1_RX_vect ) //IHM
{
char tmp;
tmp = UDR1; /* on récupère les données arrivant par RS232 dans tmp */
if(tmp == 0x0A) /* quand on arrive au caractère de saut de ligne */
{
index_ligne++; /* incrémente index_ligne */
index_caractere=0; /* on remet index_caractère à 0 */
}
else if(tmp != 0x0D) /* si tmp != retour chariot */
{
bufferISR[index_ligne][index_caractere] = tmp; /* on met les caractère de tmp dans le buffer */
index_caractere++; /* index_caractere incrémentation */
}
}
J'ai même réécrie mes propres fonction strlen et strcmp :
longueur_chaine = strlen
unsigned char longueur_chaine(const char* chaine)
{
int nombreDeCaracteres = 0;
char caractereActuel = 0;
do
{
caractereActuel = chaine[nombreDeCaracteres];
nombreDeCaracteres++;
}
while(caractereActuel != '\0'); // On boucle tant qu'on n'est pas arrivé à l'\0
nombreDeCaracteres--; // On retire 1 caractère de long pour ne pas compter l'\0
return nombreDeCaracteres;
}
comparer_chaine = strcmp
int comparer_chaines(const char* chaine1, const char* chaine2)
{
long i = 0;
long caractere_egal = 0;
long taille1 = longueur_chaine(chaine1);
long taille2 = longueur_chaine(chaine2);
//on verifie d'abord s'elles ont la meme longueur
if(taille1 == taille2)
{
for(i = 0 ; i < taille1 ; i++)
{
if(chaine1[i] == chaine2[i])
{
caractere_egal++;
}
}
if(caractere_egal == taille1)
{
return 1;
}
else return 0;
}
else return 0;
}
et maintenant voici mon programme main (ou j'ai comme vous pouvez le constater tester ce que Redtux ma proposé):
int main(void)
{
int i;
int n=0;
unsigned char ret;
unsigned char bufferfinal[256];
unsigned char index_page = 0;
const char* EndOfFile = ":00000001FF";
unsigned short len1 = 0;
unsigned short len2 = 0;
// Set the interrupt vector to the start of the bootflash
cli(); // disable interrupt in order to move the interrupt vector
MCUCR = (1<<IVCE);
MCUCR = (1<<IVSEL);
sei(); //re-enable the interrupt
initIO();
initUSART1();
initVariateur(); //Initialise le variateur pour que le moteur reste bloqué pendant une mise à jour soft.
while(1)
{
PORTJ &= ~(1<<LED1);
PORTJ &= ~(1<<LED2);
PORTJ &= ~(1<<LED3);
PORTJ &= ~(1<<LED4);
len1 = strlen(bufferISR[index_ligne]);
len2 = strlen(EndOfFile);
n = memcmp(bufferISR[index_ligne], EndOfFile,11);
if( (index_ligne >= 16) || (n == 0) )
{
for(i=0; i<index_ligne; i++)
{
ret = checksyntaxe(bufferISR[i], &bufferfinal[i*16]);
if(ret == SYNTAXE_ERREUR)
break;
}
if(ret == SYNTAXE_OK)
{
boot_program_page(index_page,&bufferfinal[i]);
index_page = index_page + 256;
}
index_ligne=0;
}
}
return 0;
}
Ce que je trouve bizarre, c'est que quand je fait un strcmp ou un memcmp (ou avec mes fonction longueur_chaine...) mon programme ne rentre même plus dans le while(1), les 4LEds de s'allume même plus, mais quand j'enlève, cela refonctionne normalement...
Je pensse que l'erreur vient de mon bufferISR[index_ligne] mais ou précisement?!
Voyer vous quelques chose qui cloche? en tout cas mon compilo n'indique aucune erreur ou warning .
Tu n'as pas suivi mon "détail d'importance": dans ta fonction ISR, au caractère 0x0A, il te faut ajouter un '\0' pour terminer la chaine, sinon tu ne sais pas, en mémoire où se termine la chaine.
D'autant que tu as réécris la fonction longueur_chaine, et tu vois vois bien que tu boucles tant que tu ne rencontre pas de '\0'. Or tu n'en mets aucun dans ta chaine, donc la boucle s'arrêtera là où elle rencontrera un '\0' en mémoire.
D'autant que tu as réécris la fonction longueur_chaine, et tu vois vois bien que tu boucles tant que tu ne rencontre pas de '\0'. Or tu n'en mets aucun dans ta chaine, donc la boucle s'arrêtera là où elle rencontrera un '\0' en mémoire.
Oui mais le soucie ne vient pas de la CRicky car 0x0A en hexadecimal correspond au caractère '\0' en gros dans ma fonction ISR si tmp = 0x0A(qui veut dire saut de ligne ou \0) j'incrémente index_ligne puis je remet les caractère a 0.
Puis tantque tmp différent de 0x0D ( 0x0D = \n = retour chariot) je met tous les caractère dans mon bufferISR.
Je pensse que tu à mal compris mes explications et jen suis désolé, c'est vrai que le problème est compliqué à serner...
Puis tantque tmp différent de 0x0D ( 0x0D = \n = retour chariot) je met tous les caractère dans mon bufferISR.
Je pensse que tu à mal compris mes explications et jen suis désolé, c'est vrai que le problème est compliqué à serner...
j'ai rajouter le caractère \0 comme tu me la demander :
en faisant cela se warning aparé :
Si je rajoute (char*) devant index_caractere cela m'enlève le warning.
Dans mon main comment dois-je déclarer ma ligne EOF?
Pour le moment je la déclare ainsi :
Je dois rajouter le caractère \0 à la fin ( const char* EndOfFile = ":00000001FF\0"); ??
et je compare les deux chaines de la sorte avec strcmp :
Cela est-il correct?
ISR( USART1_RX_vect ) //IHM
{
unsigned char tmp;
tmp = UDR1;
if(tmp != 0x0D)
{
bufferISR[index_ligne][index_caractere] = tmp;
index_caractere++;
}
else if(tmp == 0x0A)
{
bufferISR[index_ligne][strlen((char*)index_caractere)+1] = 0x00; /* <===== =====ici */
index_ligne++;
index_caractere =0;
}
en faisant cela se warning aparé :
Citation :
warning: passing argument 1 of 'strlen' makes pointer from integer without a castSi je rajoute (char*) devant index_caractere cela m'enlève le warning.
Dans mon main comment dois-je déclarer ma ligne EOF?
Pour le moment je la déclare ainsi :
const char* EndOfFile = ":00000001FF";
Je dois rajouter le caractère \0 à la fin ( const char* EndOfFile = ":00000001FF\0"); ??
et je compare les deux chaines de la sorte avec strcmp :
if( (index_ligne >= 16) || (strcmp(bufferISR[index_ligne],EndOfFile) == 0) )
Cela est-il correct?
Après des heures et des heures de recherche, j'ai trouvé d'ou vient le problème, mais je ne sais pas pourquoi pose problème dans mon cas.
Le problème vient de la ligne :
Et plus précisément du :00000001FF.
Pourtant cette ligne indique la fin de chaque fichier d'un .hex et je ne voie vraiment pas pourquoi elle pose problème en sachant que je l'écrie et l'appel correctement dans ma fonction memcmp :
A chaque fois que je rajoute une ligne avec la chaine 00000001FF. mon bootloader plante et démarre directement dans la partie application =/
J'ai tout essayer, ajouter un \0 en fin de ligne mais rien y fait, surment que mon bon vieux µcontroleur ne veux pas me laisser mener mon projet à bien
Le problème vient de la ligne :
const char *EndOfFile = ":00000001FF";
Et plus précisément du :00000001FF.
Pourtant cette ligne indique la fin de chaque fichier d'un .hex et je ne voie vraiment pas pourquoi elle pose problème en sachant que je l'écrie et l'appel correctement dans ma fonction memcmp :
(memcmp(bufferISR[index_ligne],EndOfFile,11)==0)
A chaque fois que je rajoute une ligne avec la chaine 00000001FF. mon bootloader plante et démarre directement dans la partie application =/
J'ai tout essayer, ajouter un \0 en fin de ligne mais rien y fait, surment que mon bon vieux µcontroleur ne veux pas me laisser mener mon projet à bien
strlen((char*)index_caractere)+1
C'est quoi ça ?
Tu prends un entier, certainement inférieur à 4096 (par exemple 9) puisque c'est l'index de ligne. Tu fais un cast explicite en pointeur, c'est-à-dire que tu fais un pointeur qui va pointer à l'adresse mémoire 0x00000009. Comme c'est une adresse mémoire inférieure à 0x00001000, sous windows, une exception de type pointeur NULL est soulevé. Tu vas lire n'importe où en mémoire.
Fait exactement comme pour un caractère normal, sauf qu'au lieu de mettre tmp, tu mets '\0', et ne mets pas de +1 puisque c'est déjà fait.
Je vient enfain de trouver d'ou vener mon problème, après 1semaine de recherche sur des \0 ou des fonctions qui soit disant ne marche pas j'ai découvert que les fonctions de bootloader étais spéciale dans les ATMEGA 2560, enfaite j'ai tester mon code dans ma partie application, il a fonctionner, mais il ne fonctionné pas dans la partie bootloader tout sa à cause d'un flag du Makefile :
Merci de votre aide et dsl de vous avoir embété avec des problème que vous n'auriez pas pu trouver (apar si cela vous est déjà arriver ^^)
Et je m'excuse de l'acharnement que l'on a fait subir au caractère \0 qui n'avais rien a voir la dedans vu que dans mon bufferISR j'y met des octets et non une chaine de caractère.
Si j'ai rebesoin de votre aide je vous fais signe
Merci encore
CFLAGS += -fno-jump-tables
CFLAGS += -fno-unit-at-a-time
Merci de votre aide et dsl de vous avoir embété avec des problème que vous n'auriez pas pu trouver (apar si cela vous est déjà arriver ^^)
Et je m'excuse de l'acharnement que l'on a fait subir au caractère \0 qui n'avais rien a voir la dedans vu que dans mon bufferISR j'y met des octets et non une chaine de caractère.
Si j'ai rebesoin de votre aide je vous fais signe
Merci encore
Lassé par la pub ? Créez un compte