Téléchargé 11 fois
Vote des utilisateurs
0
0
Détails
Licence : Non renseignée
Mise en ligne le 1er décembre 2010
Plate-formes :
Linux, Mac, Windows
Langue : Français
Référencé dans
Navigation
Remplacer toutes les occurrences d'une sous-chaîne
Remplacer toutes les occurrences d'une sous-chaîne
Remplace toutes les occurrences de Avant par Apres dans la chaine txt, puis renvoie un pointeur sur la nouvelle chaîne créée. Renvoie NULL si txt ne contient aucune occurrence de Avant.
Bonjour,
Très pratique cette fonction ! merci.
Cependant attention les valeurs de retour des allocations ne sont pas testés, elles sont suivis par des copies -> segfault.
Bonne journée
Très pratique cette fonction ! merci.
Cependant attention les valeurs de retour des allocations ne sont pas testés, elles sont suivis par des copies -> segfault.
Bonne journée
Bonjour,
Ton code actuel réussit bien les tests suivants :
Dans la suite de mon message, je vais noter N le nombre d'occurrences de Avant dans txt.
Je propose les améliorations suivantes :
Ton code actuel réussit bien les tests suivants :
Code : | Sélectionner tout |
1 2 3 4 5 | char* res1 = str_replace("O_O_O_O_O_O", "O_O", "XY"); assert(0 == strcmp(res1, "XY_XY_XY")); char* res2 = str_replace("O_O_O_O_O_O", "O_O", ""); assert(0 == strcmp(res2, "__")); |
Je propose les améliorations suivantes :
- Si N est non nul, Ton code fait un appel à malloc et N+1 appels à realloc. Il serait plus performant de calculer N puis de faire une seule allocation :
Code : Sélectionner tout TxtRetour = (char *) malloc(strlen(txt) - N*strlen(Avant) + N*strlen(Apres) + 1);
- Si une allocation échoue, la fonction devrait retourner NULL.
- Il y a un commentaire à corriger :
Code : Sélectionner tout 1
2
3
4
5/* Aucune occurrences : renvoie simplement une copie de la chaine */ if (pos == NULL) { return NULL; }
- Il y a un bout de ton code qui est de la forme :
Code : Sélectionner tout 1
2
3
4
5
6BOUT_DE_CODE_B; while(condition) { BOUT_DE_CODE_A; BOUT_DE_CODE_B; }
Code : Sélectionner tout 1
2
3
4
5
6
7/* Ajoute la chaîne de remplacement */ Long = strlen (Apres); strncpy (TxtRetour + PosTxtRetour, Apres, Long); PosTxtRetour += Long; /* Cherche la prochaine occurrence */ pos = strstr (txt, Avant);
Code : Sélectionner tout 1
2
3
4
5
6
7while(true) { BOUT_DE_CODE_B; if(!codition) break; BOUT_DE_CODE_A; }
- Au début de ta fonction, je te conseille d'ajouter :
Code : Sélectionner tout 1
2
3assert(strlen(Avant) > 0); if(strlen(Avant) == 0) return NULL;
- Dans ton premier appel à realloc, tu as bien pensé à convertir le résultat en (char *). Il faudrait aussi le faire pour ton appel à malloc et ton autre appel à realloc. Ainsi, le code de ta fonction compilera aussi en C++.
- Pour aller plus loin, tu pourrais factoriser le code en fournissant une nouvelle fonction str_replace_without_alloc utile aux utilisateurs qui voudraient gérer la mémoire autrement :
Code : Sélectionner tout 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// nombre d'occurrences de substring dans txt // retourner -1 si substring est une chaîne vide int str_count(const char *txt, const char *substring) { // ... } // remplacer toutes les occurrences de Avant par Apres dans la chaine txt // retourner false en cas d'erreur bool str_replace_without_alloc(char *Resultat, size_t tailleMaxResultat, const char *txt, const char *Avant, const char *Apres) { assert(Resultat != txt); // ... } char *str_replace(const char *txt, const char *Avant, const char *Apres) { char* TxtRetour = NULL; assert(strlen(Avant) > 0); if(strlen(Avant) == 0) return TxtRetour; const int N = str_count(txt, Avant); if(N <= 0) return TxtRetour; const size_t tailleTxtRetour = strlen(txt) - N*strlen(Avant) + N*strlen(Apres); TxtRetour = (char *) malloc(tailleTxtRetour + 1); if(TxtRetour == NULL) return TxtRetour; if(!str_replace_without_alloc(TxtRetour, tailleTxtRetour, txt, Avant, Apres)) { free(TxtRetour); TxtRetour = NULL; } return TxtRetour; }
Developpez.com décline toute responsabilité quant à l'utilisation des différents éléments téléchargés.