Votre question

Utilisation de strcmp

Tags :
  • Pointer
  • Programmation
Dernière réponse : dans Programmation
22 Avril 2010 10:18:03

Bonjours tout le monde :hello: 
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 cast
warning: passing argument 2 of 'strcmp' makes pointer from integer without a cast


et voici mon code :
  1. 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!!! :bounce: 

Autres pages sur : utilisation strcmp

22 Avril 2010 13:41:21

salut,
il faudrait que tu donne la déclaration de bufferISR pour voir son type, pour strcmp il faut que ça soit du char*.
sinon pour enlever le 2eme warning je pense que
  1. if(strcmp(bufferISR[index_ligne][0], (char*)":00000001FF")==0)

devrait faire l'affaire.
m
0
l
a b L Programmation
22 Avril 2010 22:54:53

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.
m
0
l
Contenus similaires
23 Avril 2010 15:55:48

Merci pour vos réponse mais cela ne fonctionne toujours pas :cry: 

Voici la ligne qui me pose problème dans mon main :

  1. 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 :heink: 

voila comment je déclare mon bufferISR :

  1. #define CAR 45
  2. #define NBR_LIGNES 16
  3.  
  4. 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 :pfff: 

m
0
l
23 Avril 2010 17:43:37

Comme la fait remarqué CRicky il serait peut être préférable d'examiner ça avec un memcmp() !

  1. const char* EndOfFile = ":00000001FF";
  2. int n;
  3. ...
  4.  
  5. len1 = strlen(bufferISR[index_ligne]);
  6. len2 = strlen(EndOfFile );
  7. n = memcmp ( bufferISR[index_ligne], EndOfFile , len1>len2?len1:len2 );
  8.  
  9. if( (index_ligne >= 16) || (n == 0) )



Je ne garantis rien, fais longtemps que je n'ai pas fait de C ...
m
0
l
a b L Programmation
23 Avril 2010 19:56:23

Je pense que dans bufferISR, il a mis toute la ligne, donc je ne ferais pas de strlen dessus, et prendrais directement la taille de la chaine fixe.
m
0
l
27 Avril 2010 14:12:42

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 :
  1. /************ Variables Globales **************/
  2. volatile int index_ligne;
  3. volatile int index_caractere;
  4. char bufferISR[NBR_LIGNES+1][CAR];
  5. /*******************************************/


Voici ma fonction ISR ou je récupère les données arrivant par la liaison RS232 :

  1. ISR( USART1_RX_vect ) //IHM
  2. {
  3. char tmp;
  4.  
  5. tmp = UDR1; /* on récupère les données arrivant par RS232 dans tmp */
  6.  
  7. if(tmp == 0x0A) /* quand on arrive au caractère de saut de ligne */
  8. {
  9. index_ligne++; /* incrémente index_ligne */
  10. index_caractere=0; /* on remet index_caractère à 0 */
  11. }
  12.  
  13. else if(tmp != 0x0D) /* si tmp != retour chariot */
  14. {
  15. bufferISR[index_ligne][index_caractere] = tmp; /* on met les caractère de tmp dans le buffer */
  16. index_caractere++; /* index_caractere incrémentation */
  17.  
  18. }
  19.  
  20.  
  21. }


J'ai même réécrie mes propres fonction strlen et strcmp :

longueur_chaine = strlen
  1. unsigned char longueur_chaine(const char* chaine)
  2. {
  3. int nombreDeCaracteres = 0;
  4. char caractereActuel = 0;
  5.  
  6. do
  7. {
  8. caractereActuel = chaine[nombreDeCaracteres];
  9. nombreDeCaracteres++;
  10. }
  11. while(caractereActuel != '\0'); // On boucle tant qu'on n'est pas arrivé à l'\0
  12.  
  13. nombreDeCaracteres--; // On retire 1 caractère de long pour ne pas compter l'\0
  14.  
  15. return nombreDeCaracteres;
  16. }


comparer_chaine = strcmp
  1. int comparer_chaines(const char* chaine1, const char* chaine2)
  2. {
  3. long i = 0;
  4. long caractere_egal = 0;
  5. long taille1 = longueur_chaine(chaine1);
  6. long taille2 = longueur_chaine(chaine2);
  7.  
  8. //on verifie d'abord s'elles ont la meme longueur
  9. if(taille1 == taille2)
  10. {
  11. for(i = 0 ; i < taille1 ; i++)
  12. {
  13. if(chaine1[i] == chaine2[i])
  14. {
  15. caractere_egal++;
  16. }
  17. }
  18. if(caractere_egal == taille1)
  19. {
  20. return 1;
  21. }
  22. else return 0;
  23. }
  24. else return 0;
  25. }


et maintenant voici mon programme main (ou j'ai comme vous pouvez le constater tester ce que Redtux ma proposé):

  1. int main(void)
  2. {
  3. int i;
  4. int n=0;
  5. unsigned char ret;
  6. unsigned char bufferfinal[256];
  7. unsigned char index_page = 0;
  8. const char* EndOfFile = ":00000001FF";
  9. unsigned short len1 = 0;
  10. unsigned short len2 = 0;
  11.  
  12. // Set the interrupt vector to the start of the bootflash
  13. cli(); // disable interrupt in order to move the interrupt vector
  14. MCUCR = (1<<IVCE);
  15. MCUCR = (1<<IVSEL);
  16. sei(); //re-enable the interrupt
  17.  
  18. initIO();
  19. initUSART1();
  20. initVariateur(); //Initialise le variateur pour que le moteur reste bloqué pendant une mise à jour soft.
  21.  
  22. while(1)
  23. {
  24. PORTJ &= ~(1<<LED1);
  25. PORTJ &= ~(1<<LED2);
  26. PORTJ &= ~(1<<LED3);
  27. PORTJ &= ~(1<<LED4);
  28.  
  29. len1 = strlen(bufferISR[index_ligne]);
  30. len2 = strlen(EndOfFile);
  31. n = memcmp(bufferISR[index_ligne], EndOfFile,11);
  32.  
  33. if( (index_ligne >= 16) || (n == 0) )
  34. {
  35.  
  36. for(i=0; i<index_ligne; i++)
  37. {
  38. ret = checksyntaxe(bufferISR[i], &bufferfinal[i*16]);
  39. if(ret == SYNTAXE_ERREUR)
  40. break;
  41. }
  42. if(ret == SYNTAXE_OK)
  43. {
  44. boot_program_page(index_page,&bufferfinal[i]);
  45. index_page = index_page + 256;
  46. }
  47.  
  48. index_ligne=0;
  49. }
  50.  
  51. }
  52.  
  53. return 0;
  54. }


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... :cry: 
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 .
m
0
l
a b L Programmation
27 Avril 2010 20:51:42

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.

m
0
l
28 Avril 2010 15:30:48

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...
m
0
l
a b L Programmation
28 Avril 2010 20:49:40

alors:
1. Ton 0x0A, tu ne le mets jamais dans ton buffer
2. '\0' == 0x00

Moi, je te dis de mettre en fin de ligne le caractère 0x00, sinon comment veux-tu que ton programme sache où se termine la ligne en mémoire ?
m
0
l
29 Avril 2010 08:57:11

Je vois enfain dese que tu veux dire CRicky :)  mais le soucie c'est que je n'arrive pas à l'appliquer, pourrai-tu me montrer un exemple du code au qu'elle tu pensse stp ?
m
0
l
29 Avril 2010 09:53:16

j'ai rajouter le caractère \0 comme tu me la demander :

  1. ISR( USART1_RX_vect ) //IHM
  2. {
  3. unsigned char tmp;
  4.  
  5. tmp = UDR1;
  6.  
  7. if(tmp != 0x0D)
  8. {
  9. bufferISR[index_ligne][index_caractere] = tmp;
  10. index_caractere++;
  11. }
  12.  
  13. else if(tmp == 0x0A)
  14. {
  15. bufferISR[index_ligne][strlen((char*)index_caractere)+1] = 0x00; /* <===== =====ici */
  16. index_ligne++;
  17. index_caractere =0;
  18. }

en faisant cela se warning aparé :
Citation :
warning: passing argument 1 of 'strlen' makes pointer from integer without a cast


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 :
  1. 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 :
  1. if( (index_ligne >= 16) || (strcmp(bufferISR[index_ligne],EndOfFile) == 0) )


Cela est-il correct?
m
0
l
29 Avril 2010 14:54:28

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 :

  1. 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 :
  1. (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 :heink: 
m
0
l
a b L Programmation
29 Avril 2010 21:12:40

  1. 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.
m
0
l
30 Avril 2010 14:52:57

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 :

  1. CFLAGS += -fno-jump-tables
  2. 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 :whistle: 
Merci encore :hello: 
m
0
l
a b L Programmation
30 Avril 2010 20:01:55

OK, effectivement, tu n'as pas besoin du \0 puisque tu as la taille.
m
0
l
Tom's guide dans le monde
  • Allemagne
  • Italie
  • Irlande
  • Royaume Uni
  • Etats Unis
Suivre Tom's Guide
Inscrivez-vous à la Newsletter
  • ajouter à twitter
  • ajouter à facebook
  • ajouter un flux RSS