couper une chaîne [résolu avec strtok]

couper une chaîne [résolu avec strtok] - C - Programmation

Marsh Posté le 22-12-2005 à 13:53:48    

Salut à tous,  
 
J'ai regardé sur le forum quelles solutions apporter à mon problème (pourtant simple) mais rien ne m'a aidé jusqu'à présent.
 
le problème est simple :
j'ai une chaîne au format FAM:REF que je veux séparer en deux à partir du ':'
 
voilà mon code avec quelques commentaires pr expliquer ce que je fais.

Code :
  1. char tcTmp[la_longueur_max_de_mon_parametre];
  2. int iPosDeuxPoints;
  3. char *ptcFam;
  4. char *ptcRef;
  5. // fin des déclarations
  6. strcpy(tcTmp,la_source_de_mon_parametre);
  7. iPosDeuxPoints = (int)strchr(tcTmp,':');
  8. // j'ai la position des deux points dans ma chaîne,  
  9. // qui est aussi un pointeur sur la sous-chaîne commencant par ':'
  10. strncpy(ptcFam,tcTmp,(iPosDeuxPoints-(int)tcTmp));
  11. // aucun problème, j'ai bien dans ptcFam 'FAM'
  12. /* Ensuite : mon ptcRef = la chaîne pointée par iPosDeuxPoints+1 puisque je ne veux pas du ':'.
  13. j'ai essayé aussi strcpy(ptcRef,(char*)(iPosDeuxPoints+sizeof(char))  : */
  14. ptcRef=(char*)(iPosDeuxPoints+sizeof(char));
  15. // => là ca plante !! j'ai n'importe quoi dans ptcRef... et mon programme crashe.


 
J'avoue ne pas comprendre, sur le papier ma solution me paraît ok ...
J'ai exploré la voie du strtok qui ne m'a pas aidé.
 
Toute aide est la bienvenue  :jap:  :jap:  
 
j'avoue retourner le pb dans tous les sens, je ne comprends pas !

Message cité 1 fois
Message édité par denzz le 22-12-2005 à 15:02:46
Reply

Marsh Posté le 22-12-2005 à 13:53:48   

Reply

Marsh Posté le 22-12-2005 à 13:58:14    

denzz a écrit :


Code :
  1. // => là ca plante !! j'ai n'importe quoi dans ptcRef... et mon programme crashe.



 
 
Tu m'étonnes : où sont les allocations mémoire de *ptcFam et *ptcRef ?
Ce ne sont que des pointeurs, ces variables ne contiennent que des adresses. Ici, des adresses vers n'importe où, en tout cas pas sur un bloc mémoire valide.
 
=> cf. malloc()
 
 

denzz a écrit :

J'ai exploré la voie du strtok qui ne m'a pas aidé.


 
Essaie à nouveau, et poste le code de ce qui ne fonctionne pas.


Message édité par Elmoricq le 22-12-2005 à 13:58:41
Reply

Marsh Posté le 22-12-2005 à 14:44:29    

mmh.
effectivement  :sweat: les malloc !
 
reprenons :  

Code :
  1. char tcTmp[la_longueur_max_de_mon_parametre];
  2. int iPosDeuxPoints;
  3. char *ptcFam;
  4. char *ptcRef;
  5. // fin des déclarations
  6. // mallocation :
  7. ptcFam = (char*) malloc(sizeof(la_taille_qui_va_bien)); //s'il fallait que j'alloue, pk mon 1er strcpy ne pose aucun pb ??  
  8. // --> je suppute que strnpcy = copie de la val du pointeur et ajout de '\0' à la taille voulue mais on m'a dit que non pas du tout ??
  9. ptcRef = (char*) malloc(sizeof(la_taille_qui_va_bien));
  10. strcpy(tcTmp,la_source_de_mon_parametre);
  11. iPosDeuxPoints = (int)strchr(tcTmp,':');
  12. // j'ai la position des deux points dans ma chaîne,  
  13. // qui est aussi un pointeur sur la sous-chaîne commencant par ':'
  14. strncpy(ptcFam,tcTmp,(iPosDeuxPoints-(int)tcTmp));
  15. // aucun problème, j'ai bien dans ptcFam 'FAM'
  16. /* Ensuite : mon ptcRef = la chaîne pointée par iPosDeuxPoints+1 puisque je ne veux pas du ':'.
  17. j'ai essayé aussi strcpy(ptcRef,(char*)(iPosDeuxPoints+sizeof(char))  : */
  18. strcpy(ptcRef,(char*)(iPosDeuxPoints+sizeof(char)));
  19. // => là ca plante !! j'ai n'importe quoi dans ptcRef... et mon programme crashe.


 
 
ca change rien :'(
 
quand au strtok, j'avais testé comme ca :

Code :
  1. char tcTmp[la_longueur_max_de_mon_parametre];
  2. char *ptcFam = (char *)malloc(la_taille_qui_faut);
  3. char *ptcRef = (char *)malloc(la_taille_qui_faut);
  4. int iLgFam;
  5. ptcFam = strtok(tcTmp,":" );
  6. /* j'avais pensé à ca :
  7. iLgFam = strlen(ptcFam);
  8. strcpy(ptcRef,(char*)(tcTmp+iLgFam)); // => tcTmp+iLgFam doit logiquement pointer sur le tableau de caractères commencant juste après le ':'
  9. */
  10. // et en fait  comme ca c bon :  
  11. ptcRef = strtok(NULL,":" );


 
 :jap:  :jap:  
Merci pour ton aide, une aide extérieure permet toujours de faire avancer le pb :p

Reply

Marsh Posté le 22-12-2005 à 15:07:24    

denzz a écrit :


Code :
  1. ptcFam = (char*) malloc(sizeof(la_taille_qui_va_bien));



 
Le cast est inutile. Et "sizeof" permet de déterminer le nombre de bytes pour un type particulier :
 

Code :
  1. ptcFam = malloc( la_taille_qui_va_bien * sizeof *ptcFam);


(en espérant que "la_taille_qui_va_bien" corresponde à la taille de ce que tu dois copier + le caractère null de fin de chaîne)
 

denzz a écrit :


Code :
  1. //s'il fallait que j'alloue, pk mon 1er strcpy ne pose aucun pb ??



 
Coup de bol.  
Le propre des opérations foireuses en mémoire, c'est que le comportement est aléatoire.
Ca passe ou ça casse. Là, c'est passé. Demain, ça aurait peut-être cassé.
 
 

denzz a écrit :


Code :
  1. // --> je suppute que strnpcy = copie de la val du pointeur et ajout de '\0' à la taille voulue mais on m'a dit que non pas du tout ??



 
N'écoute plus "on" :

Citation :

strcpy(), strncpy(), strlcpy()
     The strcpy() function copies string s2 to s1, including  the
     terminating  null character
, stopping after the null charac-
     ter has been copied. The strncpy() function copies exactly n
     bytes,  truncating  s2  or  adding  null characters to s1 if
     necessary. The result will not  be  null-terminated  if  the
     length of s2 is n or more.  Each function returns s1.


 
 

denzz a écrit :

Code :
  1. iPosDeuxPoints = (int)strchr(tcTmp,':');



 
int ? [:mlc]
Pourquoi, int ?
strchr retourne un char*, soit une adresse, non un entier.
"iPosDeuxPoints" doit être de type char* aussi.
 
La suite plus tard...

Reply

Marsh Posté le 22-12-2005 à 15:33:51    

pour mon sizeof, il s'agit bien de récupérer la taille d'un champ d'une structure, donc à ce niveau pas de pb.
 
merci pour ces éclaircissements, mais je pense que je vais continuer à écouter 'on' puisqu' "on" m'a dit que je me trompais, ce que tu me confirmes avec cette belle citation ;)  
 
en ce qui concerne le cast en int, c'est en effet hasardeux, je pensais (et je n'écouterais plus mon cerveau) par extension adresse = int, et je me sentais assez chaud pr manipuler les adresses :p  
 

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed