Suite à la question que j'ai posé sur le forum, j'ai fait une petite
fonction qui découpe une chaine suivant un délimiteur.
La fonction permet de choisir si on accpete ou non les mots vides.
Elle retourne un tableau de chaines de caractères, terminé par NULL.
Le code est compilé sous windows avec gcc donc la fonction doit être portable sous linux/unix.
(quoique que j'ai des doutes sur system("pause") )
Source / Exemple :
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// Retour tableau des chaines recupérer. Terminé par NULL.
// chaine : chaine à splitter
// delim : delimiteur qui sert à la decoupe
// vide : 0 : on n'accepte pas les chaines vides
// 1 : on accepte les chaines vides
char** split(char* chaine,const char* delim,int vide){
char** tab=NULL; //tableau de chaine, tableau resultat
char *ptr; //pointeur sur une partie de
int sizeStr; //taille de la chaine à recupérer
int sizeTab=0; //taille du tableau de chaine
char* largestring; //chaine à traiter
int sizeDelim=strlen(delim); //taille du delimiteur
largestring = chaine; //comme ca on ne modifie pas le pointeur d'origine
//(faut ke je verifie si c bien nécessaire)
while( (ptr=strstr(largestring, delim))!=NULL ){
sizeStr=ptr-largestring;
//si la chaine trouvé n'est pas vide ou si on accepte les chaine vide
if(vide==1 || sizeStr!=0){
//on alloue une case en plus au tableau de chaines
sizeTab++;
tab= (char**) realloc(tab,sizeof(char*)*sizeTab);
//on alloue la chaine du tableau
tab[sizeTab-1]=(char*) malloc( sizeof(char)*(sizeStr+1) );
strncpy(tab[sizeTab-1],largestring,sizeStr);
tab[sizeTab-1][sizeStr]='\0';
}
//on decale le pointeur largestring pour continuer la boucle apres le premier elément traiter
ptr=ptr+sizeDelim;
largestring=ptr;
}
//si la chaine n'est pas vide, on recupere le dernier "morceau"
if(strlen(largestring)!=0){
sizeStr=strlen(largestring);
sizeTab++;
tab= (char**) realloc(tab,sizeof(char*)*sizeTab);
tab[sizeTab-1]=(char*) malloc( sizeof(char)*(sizeStr+1) );
strncpy(tab[sizeTab-1],largestring,sizeStr);
tab[sizeTab-1][sizeStr]='\0';
}
else if(vide==1){ //si on fini sur un delimiteur et si on accepte les mots vides,on ajoute un mot vide
sizeTab++;
tab= (char**) realloc(tab,sizeof(char*)*sizeTab);
tab[sizeTab-1]=(char*) malloc( sizeof(char)*1 );
tab[sizeTab-1][0]='\0';
}
//on ajoute une case à null pour finir le tableau
sizeTab++;
tab= (char**) realloc(tab,sizeof(char*)*sizeTab);
tab[sizeTab-1]=NULL;
return tab;
}
int main(){
int i;
int ret;
char* str="foo|bar||baz|bar|";
char** tab;
printf("Chaine initiale : %s \n",str);
tab=split(str,"|",0);
//affichage du resultat
for(i=0;tab[i]!=NULL;i++) {
printf("%d : %s\n",i,tab[i]);
//au passge je désalloue les chaines
free(tab[i]);
}
free(tab);
printf("\n");
tab=split(str,"|",1);
//affichage du resultat
for(i=0;tab[i]!=NULL;i++) {
printf("%d : %s\n",i,tab[i]);
//au passge je désalloue les chaines
free(tab[i]);
}
free(tab);
system("pause");
}
Conclusion :
Le tableau est alloué dynamiquement => n'oubliez pas de désallouer.
Merci à buno et steve_clamage pour leur info sur le forum.
Puis si vous trouver des bug ou si vous voulez noter, un chtit commentaire.
Voila a quoi ressemble la sortie :
chaine init : foo|bar||baz|bar|
0 : foo
1 : bar
2 : baz
3 : bar
0 : foo
1 : bar
2 :
3 : baz
4 : bar
5 :
Appuyez sur une touche pour continuer...
Vous n'êtes pas encore membre ?
inscrivez-vous, c'est gratuit et ça prend moins d'une minute !
Les membres obtiennent plus de réponses que les utilisateurs anonymes.
Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.
Le fait d'être membre vous permet d'avoir des options supplémentaires.