Existe-t-il un moyen d’améliorer cette fonction qui remplace les occurrences de sous-chaînes par une autre chaîne dans une chaîne allouée par malloc?

Je suis très nouveau en C et j’ai décidé de créer une fonction appelée str_replace qui remplace les chaînes dans les chaînes qui ont été créées avec malloc. Cela semble fonctionner, mais n’importe qui peut-il trouver une marge de progression.

Tout conseil sera apprécié. J’aimerais savoir si les gens pensent que trouver le nombre d’occurrences pour calculer la nouvelle taille de chaîne était une bonne idée et si mon utilisation de pointeurs est logique.

#include  #include  #include  char * str_replace(char * ssortingng,char * find,char * replace){ //Replaces each occurence of a particular ssortingng inside a malloc-made ssortingng with another ssortingng char * pos = ssortingng; size_t replace_size = strlen(replace); size_t find_size = strlen(find); size_t excess = replace_size - find_size; //Get number of occurences int x = 0; while (1) { pos = strstr(pos,find); if (pos == NULL){ break; } pos++; x++; } if (!x){ //No occurences so return with original ssortingng return ssortingng; } char * new_ssortingng = malloc(sizeof(char)*(strlen(ssortingng) + excess*x + 1)); //Plus 1 for null termination pos = ssortingng; //Reset pointer char * ssortingng_track = ssortingng; //Used to move around ssortingng. char * new_ssortingng_begin = new_ssortingng; //Begining of new ssortingng to return while (1) { pos = strstr(pos,find); if (pos == NULL){ strcpy(new_ssortingng,ssortingng_track); //Fill in remainder break; } pos++; size_t seg_len = pos-ssortingng_track; //Length between found ssortingng and last strncpy(new_ssortingng,ssortingng_track,seg_len); //Copy ssortingng to just before pos new_ssortingng += seg_len - 1; //Go to point for replacement by adding what was added to pointer. strncpy(new_ssortingng,replace,replace_size); new_ssortingng += replace_size; //Go to point after what was replaced ssortingng_track = pos + find_size - 1; //Original ssortingng should go to point after found ssortingng. } free(ssortingng); //Remove old ssortingng return new_ssortingng_begin; //return new ssortingng } int main (int argc, const char * argv[]) { char * ssortingng = malloc(sizeof(char)*21); strcpy(ssortingng,"No,yes,no,yes,no,yes"); printf("%s\n",ssortingng); ssortingng = strreplace(ssortingng, "no", "nope"); printf("%s\n",ssortingng); free(ssortingng); ssortingng = malloc(sizeof(char)*21); strcpy(ssortingng,"No,yes,no,yes,no,yes"); printf("%s\n",ssortingng); ssortingng = strreplace(ssortingng, "hello", "nope"); printf("%s\n",ssortingng); free(ssortingng); ssortingng = malloc(sizeof(char)*21); strcpy(ssortingng,"No,yes,no,yes,no,yes"); printf("%s\n",ssortingng); ssortingng = strreplace(ssortingng, "yes", "y"); printf("%s\n",ssortingng); free(ssortingng); return 0; } 

Dans l’ensemble, c’est assez solide, certaines choses que j’aimerais suggérer

1) ne nommez pas le premier argument “chaîne” .. Je pense que c’est un peu risqué (ssortingng.h ne définit-il pas un symbole “chaîne”?)

2) Je ne libérerais pas l’ancienne chaîne dans la fonction str_replace, elle n’était pas allouée par cette fonction, elle ne devrait donc pas la libérer, mais pas vraiment important pour cet exemple, mais c’est généralement une bonne habitude. Cela signifierait également qu’il n’y a aucun besoin de la variable “ssortingng_track”, puisque le premier argument est simplement une copie d’un pointeur sur une chaîne, vous pouvez le perdre et ne pas vous soucier de savoir où il finit car il est jeté lorsque la fonction sorties.

Une suggestion: Si vous souhaitez appeler la fonction avec la syntaxe, ssortingng = str_replace(ssortingng, "no", "nope"); , alors je suggèrerais de changer le premier argument en un caractère char** . De cette façon, vous pouvez modifier directement le pointeur au lieu de supposer que l’utilisateur utilise cette notation d’appel particulière. Puisque vous libérez la chaîne d’origine, le bloc de code suivant est dangereux:

 char* str1; char* str2; str1 = malloc(SIZE_1); /* Write something into the buffer here.. */ str2 = str_replace(str1, "from", "to"); free(str1); // Whoops! Double free! 

En remplaçant le premier paramètre par un caractère char** , l’utilisateur peut libérer en toute sécurité le même pointeur que celui utilisé avec malloc quelle que soit la manière dont il a appelé la fonction. Dans ce cas, vous pouvez void votre fonction ou simplement renvoyer une copie du pointeur à la chaîne d’origine ( *ssortingng ).