TABLEAUX DE CHAINES DE CARACTÈRE: FONCTIONS IMPLODE, EXPLODE ET COUNT
BruNews
Messages postés21040Date d'inscriptionjeudi 23 janvier 2003StatutModérateurDernière intervention21 août 2019
-
9 août 2007 à 23:06
BruNews
Messages postés21040Date d'inscriptionjeudi 23 janvier 2003StatutModérateurDernière intervention21 août 2019
-
19 déc. 2008 à 11:29
Cette discussion concerne un article du site. Pour la consulter dans son contexte d'origine, cliquez sur le lien ci-dessous.
BruNews
Messages postés21040Date d'inscriptionjeudi 23 janvier 2003StatutModérateurDernière intervention21 août 2019 19 déc. 2008 à 11:29
if(strarr!=NULL && strarr[0]!=NULL)
Si strarr vaut 0, c'est badaboum garanti d'essayer de lire strarr[0].
ranzia
Messages postés1Date d'inscriptionmardi 22 novembre 2005StatutMembreDernière intervention19 décembre 2008 19 déc. 2008 à 10:57
Merci pour ce source très utile.
Voici une autre version de la fonction implode() où le délimiteur est une chaine au lieu d'un char.
/**
* Rassemble les elements d'un tableau en une chaine en les concatenant avec le separateur
* @param strarr tableau de chaine
* @param separator separateur (peut etre une chaine vide)
* @return chaine concatenee ou NULL en cas d'erreur
*/
char * implode(const char **strarr, const char *separator)
{
char *res;
int taille_strarr,taille_sep;
int i;
const char *sep;
jacqhal
Messages postés1Date d'inscriptionvendredi 11 avril 2003StatutMembreDernière intervention23 février 2008 23 févr. 2008 à 07:35
par contre quelques traitements d'erreur serait certanement bien venu en cas de dépassement de memoire ..
par ex : voici ce que j'ai fait en reprenant une partie de ce que tu avais fait..
int Explode(char* Txt, char**& return_value, char Separator /*= ';'*/)
{
if (Separator == '\0')
throw "Delimiter null";
int NumRows = 0;
char *Car = Txt;
// Calcul de la taille
while (Car != NULL) {
Car = strchr(++Car, Separator);
if (Car != NULL) { NumRows++; }
}
if (!NumRows) return 0; // Si pas de chaine a scindé , on sort.
NumRows++; //pour avoir le dernier "Mot" qui n'as pas de ';' en fin (en theorie)
Car = Txt; //Reinitialisation du pointeur
int lenWord = 0;
char *CarPtr = &(Txt[0]);
int i = 0;
int NumCar = 0;
int lenChar = strlen(&Separator); // toujours 1 mais au cas ou Separator != > char.
try {
return_value = new char * [NumRows]; //Allocation
// parcours a la recherche des chaines
while(i<NumRows) {
lenWord++;
if ((*Car == Separator) || (*Car==0)) {
return_value[i] = new char[lenWord];
strncpy(return_value[i], CarPtr, lenWord-lenChar);
CarPtr = &Txt[NumCar+lenChar];
lenWord = 0; //reinitialisation de la longueur de chaine
i++; //Element suivant dans le tableau
}
Car++; NumCar++;
};
} catch (...) {
delete [] return_value;
return 0;
}
return NumRows; // Renvoie du nombre de ligne;
}
cs_Lucky92
Messages postés180Date d'inscriptionmercredi 22 décembre 2004StatutMembreDernière intervention16 août 20122 14 août 2007 à 10:36
Le délimiteur de ta fonction explode se limite à un seul caractère. Que penses-tu d'étendre celui-ci à une chaîne de caractères, voire à une expression régulière comme en perl ?
guill76
Messages postés193Date d'inscriptionmercredi 24 août 2005StatutMembreDernière intervention 3 juin 2016 14 août 2007 à 02:33
je viens de metre à jour et d'optimiser un nouvel explode qui je pense est plus rapide que le précédent, je me suis un peu inspiré d'un autre code de brunews et j'ai rajouté la vraie gestion des champs csv avec la gestion des token.
l'allocation se fait dans le main: ce qui est + "conventionnel"
RaphAstronome
Messages postés104Date d'inscriptionsamedi 7 décembre 2002StatutMembreDernière intervention17 août 2009 13 août 2007 à 12:01
La classe string est plus lente mais est plus pratique car tu as pas à te soucier de la gestion de la mémoire, ce qui veux dire aussi que tu est en partie protégé des dépassements de buffer.
BruNews
Messages postés21040Date d'inscriptionjeudi 23 janvier 2003StatutModérateurDernière intervention21 août 2019 13 août 2007 à 09:42
Lucky92, sors le listing asm du compilo d'un exemple avec std:string et compare avec 2 pointeurs sur un buffer, tu auras la réponse.
cs_Lucky92
Messages postés180Date d'inscriptionmercredi 22 décembre 2004StatutMembreDernière intervention16 août 20122 13 août 2007 à 04:03
Salut,
J'ai une question.
C'est le deuxième sujet sur les chaînes de caractères en c/c++, qui tombe en 15 jours - l'autre sujet traitait des fonctions de type trim() ; et dans les deux cas, on a l'impression que les strings de la librairie standard du c++ ont mauvaise haleine !
D'où ma question, écris-tu des routines en C presque pur :
a - pour optimiser la vitesse et/ou la mémoire de tes applications ?
b - pour des raisons scolaires ( exercices, devoirs à la maison, ... ) ?
c - parce que tu n'aimes pas le c++ et ce qu'il est devenu avec l'avènement de la STL ?
PS : Ces deux fonctions existent également dans le langage perl sous les doux noms de join() et split(). Si elles existent, c'est qu'elles doivent bien servir à quelque chose ! Mais, même si elles ne servent à rien ni à personne, j'aime bien les sources un peu académiques...
RaphAstronome
Messages postés104Date d'inscriptionsamedi 7 décembre 2002StatutMembreDernière intervention17 août 2009 13 août 2007 à 00:52
Même si on n'en met pas dans tout les programmes je trouve que "explode" est très pratique (par contre implode nettement moins).
BruNews
Messages postés21040Date d'inscriptionjeudi 23 janvier 2003StatutModérateurDernière intervention21 août 2019 9 août 2007 à 23:37
Ben non, c'est bien là que je veux en venir. En natif, il faut se laver le cerveau du fatras qu'apporte l'usage des interprétés. Quand on les a utilisées, on se dépêche de les oublier.
Je t'assure que jamais employé de bidules de ce genre et je ne suis malheureusement plus en début de carrière.
guill76
Messages postés193Date d'inscriptionmercredi 24 août 2005StatutMembreDernière intervention 3 juin 2016 9 août 2007 à 23:28
L'utilité me parait réélle quand on les a utilisées dans d'autres languages comme php. Implode peut-être utilisée pour formater un fichier de sortie comme un .ini ou un .csv par exemple, et explode pour le lire, mais pour pas mal d'autre choses.
BruNews
Messages postés21040Date d'inscriptionjeudi 23 janvier 2003StatutModérateurDernière intervention21 août 2019 9 août 2007 à 23:06
Je n'ai jamais eu l'emploi de explode() ou implode().
A quoi peuvent-elles te servir ?
19 déc. 2008 à 11:29
Si strarr vaut 0, c'est badaboum garanti d'essayer de lire strarr[0].
19 déc. 2008 à 10:57
Voici une autre version de la fonction implode() où le délimiteur est une chaine au lieu d'un char.
/**
* Rassemble les elements d'un tableau en une chaine en les concatenant avec le separateur
* @param strarr tableau de chaine
* @param separator separateur (peut etre une chaine vide)
* @return chaine concatenee ou NULL en cas d'erreur
*/
char * implode(const char **strarr, const char *separator)
{
char *res;
int taille_strarr,taille_sep;
int i;
const char *sep;
if(strarr!=NULL && strarr[0]!=NULL)
{
taille_strarr = sizeof(strarr);
res = (char *)malloc((strlen(strarr[0])+1)*sizeof(char));
sprintf(res,"%s",strarr[0]);
if(separator==NULL)
sep = "";
else
sep = separator;
taille_sep = strlen(sep);
for(i=1;i<taille_strarr;i++)
{
res = (char *)realloc(res,(strlen(res)+taille_sep+strlen(strarr[i])+1)*sizeof(char));
sprintf(res,"%s%s%s",res,separator,strarr[i]);
}
return res;
}
return NULL;
}
23 févr. 2008 à 07:35
par ex : voici ce que j'ai fait en reprenant une partie de ce que tu avais fait..
int Explode(char* Txt, char**& return_value, char Separator /*= ';'*/)
{
if (Separator == '\0')
throw "Delimiter null";
int NumRows = 0;
char *Car = Txt;
// Calcul de la taille
while (Car != NULL) {
Car = strchr(++Car, Separator);
if (Car != NULL) { NumRows++; }
}
if (!NumRows) return 0; // Si pas de chaine a scindé , on sort.
NumRows++; //pour avoir le dernier "Mot" qui n'as pas de ';' en fin (en theorie)
Car = Txt; //Reinitialisation du pointeur
int lenWord = 0;
char *CarPtr = &(Txt[0]);
int i = 0;
int NumCar = 0;
int lenChar = strlen(&Separator); // toujours 1 mais au cas ou Separator != > char.
try {
return_value = new char * [NumRows]; //Allocation
// parcours a la recherche des chaines
while(i<NumRows) {
lenWord++;
if ((*Car == Separator) || (*Car==0)) {
return_value[i] = new char[lenWord];
strncpy(return_value[i], CarPtr, lenWord-lenChar);
CarPtr = &Txt[NumCar+lenChar];
lenWord = 0; //reinitialisation de la longueur de chaine
i++; //Element suivant dans le tableau
}
Car++; NumCar++;
};
} catch (...) {
delete [] return_value;
return 0;
}
return NumRows; // Renvoie du nombre de ligne;
}
14 août 2007 à 10:36
14 août 2007 à 02:33
l'allocation se fait dans le main: ce qui est + "conventionnel"
13 août 2007 à 12:01
13 août 2007 à 09:42
13 août 2007 à 04:03
J'ai une question.
C'est le deuxième sujet sur les chaînes de caractères en c/c++, qui tombe en 15 jours - l'autre sujet traitait des fonctions de type trim() ; et dans les deux cas, on a l'impression que les strings de la librairie standard du c++ ont mauvaise haleine !
D'où ma question, écris-tu des routines en C presque pur :
a - pour optimiser la vitesse et/ou la mémoire de tes applications ?
b - pour des raisons scolaires ( exercices, devoirs à la maison, ... ) ?
c - parce que tu n'aimes pas le c++ et ce qu'il est devenu avec l'avènement de la STL ?
PS : Ces deux fonctions existent également dans le langage perl sous les doux noms de join() et split(). Si elles existent, c'est qu'elles doivent bien servir à quelque chose ! Mais, même si elles ne servent à rien ni à personne, j'aime bien les sources un peu académiques...
13 août 2007 à 00:52
9 août 2007 à 23:37
Je t'assure que jamais employé de bidules de ce genre et je ne suis malheureusement plus en début de carrière.
9 août 2007 à 23:28
9 août 2007 à 23:06
A quoi peuvent-elles te servir ?