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
|
// remplace les chaines "from" par "to" dans "src", et stocke le résultat dans
// dst (dont la taille maximale est dstlen). Histoire de faire bien, si on a pas
// réussi à stocker le résultat dans dst, on renvoie -1
int replace_in_string(const char* src, char* dst, unsigned int dstlen, const char* from, const char* to)
{
// on va commencer par récupérer les longueurs des chaines défniies
unsigned int srclen = strlen(src);
unsigned int fromlen = strlen(from);
unsigned int tolen = strlen(to);
// on garde le dernier caractère pour rajouter le '\0'
--dstlen;
// il y a deux étapes : en premier, il faut trouver les occurences
// de from dans src. C'est une recherche de chaine classique. Pour
// s'en sortir, on maintient deux index : i est la position dans src, et
// n est le nombre de caractères de from trouvés dans src. Un troisième
// compteur nous indique la position courante dans dst, parce qu'elle n'est
// pas nécessairement égale à i.
unsigned int i = 0; // compteur sur src
unsigned int j = 0; // compteur sur dst
unsigned int n = 0; // compteur sur from
for ( ; i<srclen && j<dstlen; ++i)
{
if (src[i] != from[n])
{
// si le caractère courant de src n'est pas le caractère courant de from
// alors il faudra chercher à partir du premier caractère (et ajouter
// le caractère trouvé dans dst)
dst[j++] = src[i];
n = 0;
}
else
{
// le caractère courant de src est aussi celui de from : on est en passe
// de trouver la chaine from dans src. En fait, la condition pour que from
// ait été trouvé complètement, c'est que n soit égal à fromlen
++n;
if (n == fromlen)
{
// c'est le cas ? Alors il faut copier le contenu de to dans dst,
// en prenant garde à ne pas dépasser au delà de la taille maximale
// de dst
for (unsigned int k=0; k<tolen && j<dstlen; ++k, ++j)
{
dst[i] = to[k];
}
// on reboot la recherche
n = 0;
}
}
}
// on va pouvoir vérifier la condition d'erreur : si on a rempli dst à hauteur
// de dstlen et que src n'a pas été pris en compte complètement, alors
// c'est qu'il y a une erreur
if (i < srclen && j == dstlen) return -1;
// s'il n'y a pas eu d'erreur, alors on peut terminer : il faut rajouter le
// \0 à la fin de dst. Fort heureusement, on a gardé la place plus tôt
// avec un chouette effet de bord : dstlen étant plus court de 1 que la
// longueur réelle de dst, et j ne pouvant être supérieur à cette valeur,
// je peux directement adresser dst[j] sans risquer de problème.
dst[j] = '\0';
return 0;
} |
Partager