1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106
|
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int Fstr_ncompare(const char *t1, const char* t2, int lg)
/* Compare les chaines de caractère t1 et t2 sur une longeur lg, si ils sont strictement identiques, renvoi 1, sinon 0.
La comparaison s'arrête si la fonction atteint la fin d'une chaine de caractère, aucun risque de débordement si elles se terminent par '\0' */
{
int i;
for(i=0; i<lg; i++)
{
if (t1[i] != t2[i]) return 0;
if (t1[i] == '\0') return 1;
}
return 1;
}
int Fnb_str(const char *s, const char *sep, int taille)
/* Renvoi le nombre d'occurence de la chaine de char sep dans la chaine de char 's' de taille 'taille' */
{
if (!taille)
taille = strlen(s);
int lg_sep = strlen(sep);
int i;
int retour = 0;
for(i=0; i<taille; i++)
{
/* Si le caractère courant est le même que le premier de la chaine à rechercher... */
if (s[i] == sep[0])
{
/* On recherche si la suite dans s est strictement identique à la chaine sep */
if (Fstr_ncompare(&(s[i]), sep, lg_sep))
retour++;
}
}
return retour;
}
char **Fcoupe_ch(char *chaine, const char *separateur, unsigned int longeur)
/*
Coupe une chaine de caractère en sous chaines après chaque chaine "séparateur" (typiquement " " ou "\n"),
équivalent de la fonction split des objets chaine en python.
Si longeur vaut 0, la fonction tentera de calculer la longeur de la chaine, sinon on bouclera jusqu'a la longeur donné en argument
Tous les caractères séparateur seront remplacés par le caractère \0, du coup la chaine sera considéré comme plusieurs sous chaine.
La fonction retournera donc un pointeur vers le début de chaque sous chaine.
Le dernier élement du tableau pos_tableau vaudra NULL ce qui permettra de retrouver la fin du tableau
Le tableau renvoyé est alloué dynamiquement, penser à libérer la mémoire.
*/
{
if (!longeur) longeur = strlen(chaine);
int cpt = 0;
unsigned int i;
int lg_sep = strlen(separateur);
/* Compte le nombre de lexemes dans la chaine pour allouer la mémoire du tableau de sous chaines */
int nb_lexemes = Fnb_str(chaine, separateur, longeur) + 2;
/* Le tableau contiendra la position de chaque début de tableau: */
char **pos_tableau = malloc(nb_lexemes * sizeof(char *));
if (!pos_tableau)
return pos_tableau;
/* Envoi le pointeur de la première sous chaine dans le tableau. */
pos_tableau[0] = chaine;
/* Parcours la chaine de char et remplace les espaces par des caractères nul. */
for (i=0; i<longeur; i++)
{
/* Si le caractère courant est le même que le premier de la chaine séparateur... */
if (chaine[i] == separateur[0])
{
if (Fstr_ncompare(&(chaine[i]), separateur, lg_sep))
{
pos_tableau[++cpt] = &chaine[i+lg_sep]; /* ++cpt != cpt++, sinon il saute le premier élément. */
chaine[i] = '\0'; /* Remplace le séparateur par le caractère nul pour indique la fin de la sous chaine. */
i+=2;
}
}
}
pos_tableau[cpt+1] = NULL;
return pos_tableau;
}
int main(void)
{
/* Petit exemple... */
char test[] = "Ceci est une chaine de caractères !";
char **chaine_coupe = Fcoupe_ch(test, " ", 0);
int i = 0;
while(chaine_coupe[i])
fprintf(stdout, ": \"%s\"\n", chaine_coupe[i++]);
free(chaine_coupe);
return 0;
} |
Partager