BruNews
Messages postés21040Date d'inscriptionjeudi 23 janvier 2003StatutModérateurDernière intervention21 août 2019 16 janv. 2007 à 09:37
strtok est une vieille daube qu'il convient d'oublier cause que pas safe thread.
On fait la même chose en balladant 2 pointeurs et pas de bugs en multi thread.
SAKingdom
Messages postés3212Date d'inscriptionlundi 7 novembre 2005StatutMembreDernière intervention16 février 200915 16 janv. 2007 à 16:08
Je m'en doute. Je ne m'en sers jamais. J'utilise plutôt mes propres routines mais si je n'avais pas donné d'exemple avec strtok mais avec mes routines, quelqu'un d'autre aurais ramené cette fonction sur le planché.
Tu dois probablement être mieu placé que moi pour le savoir mais on s'écoeure à la longue de se faire dire que sa méthode de travail n'est pas bonne et qu'une fonction désuette ou boulet (sprintf) est meilleur malgré le fait que ce n'est pas vrai du tout. Ou encore, que l'on m'ignore quand je dit, par exemple, que lire un fichier tout d'un coup et traiter le buffer avec des pointeurs après est beaucoup plus rapide que de lire que par petite section à la fois. Très frustrant tout ça.
Fini de chialer... Voici donc la routine en question. À optimiser probablement (j'ai jamais eu à traiter ce genre de context). Elle stock le tout dans un tableau de pointeur:
char test[] = "salut a tous";
char *ptr[3], *c = &test[0], *d = c;
int i = 0;
SAKingdom
Messages postés3212Date d'inscriptionlundi 7 novembre 2005StatutMembreDernière intervention16 février 200915 16 janv. 2007 à 17:48
La boucle n'est pas infinie. J'ai pas beaucoup de talent dans les explications mais:
...
char *ptr[3], *c = &test[0]
char *d = c; // <- Sers à pointer sur le "début" du mot
...
while(1)
{ if(*c ' ' || *c '\n') // <- On roule jusqu'à trouver un espace ou un saut de ligne
{
*c = 0; // <- On remplace l'occurance par un 0 de fin de chaine
ptr[i++] = d; // <- On fait pointer un des pointeurs du tableau sur le mot
d = c+1; // <- On fais pointer d sur la position du second mot (+1 pour sauter l'occurance)
}
else if(!*c) { ptr[i] = d; break; } // Si on rencontre un 0, on pointe sur le dernier mot et on quitte
c++;
}
En gros, cette routine roule jusqu'à trouver une occurance. Elle remplace celle-ci par un 0 pour créé une chaine, fais pointer un des pointeurs du tableau sur la "nouvelle" chaine puis sauvegarde la première position après l'occurance (qui devrais être la première lettre d'une autre chaine) et ainsi de suite jusqu'à la rencontre du 0 de fin de chaine de la vrai chaine. Elle ne fais donc là que pointer le mot et elle quitte directement la boucle.
Attention, il ne s'agit que de pointeur. Il reste donc dépendant de la chaine principal (qui ce retrouve donc modifié). Si tu écrase la chaine principal, les pointeurs risque de ne plus pointer sur la bonne location.
Si tu veux garder la chaine principal intacte ou si tu veux la réutiliser pour autre chose, j'ai un autre code qui sauvegarde les chaines dans un tableau à 2 dimensions tout en laissant la principal inchangé. Si ça t'interesse...
SAKingdom
Messages postés3212Date d'inscriptionlundi 7 novembre 2005StatutMembreDernière intervention16 février 200915 16 janv. 2007 à 18:07
Ça fait un moment que je l'est fais celle-là elle n'est donc pas très optimisé (n'utilise pas de pointeur entre autre) mais fais tout de même l'affaire. À toi de l'optimiser et/ou modifier à tes besoins:
char buffer[] = "salut a tous";
char tab[3][10]; // <- 3 mots de chacun 9 char + 0 de fin de chaine int i 0, j 0;