J'essaie de créer une fonction en C pour remplacer toutes les occurrences d'une sous-chaîne dans une chaîne. J'ai créé ma fonction, mais cela ne fonctionne que lors de la première occurrence de la sous-chaîne dans la chaîne la plus grande.
Voici le code jusqu'à présent:
void strreplace(char string[], char search[], char replace[]){
char buffer[100];
char*p = string;
while((p=strstr(p, search))){
strncpy(buffer, string, p-string);
buffer[p-string] = '\0'; //EDIT: THIS WAS MISSING
strcat(buffer, replace);
strcat(buffer, p+strlen(search));
strcpy(string, buffer);
p++;
}
}
Je ne suis pas nouveau en programmation C, mais il me manque quelque chose ici.
Exemple: pour la chaîne de saisie "marie a pommes a", recherche de "a" et remplace par "blabla"
Dans le premier "a" est remplacé correctement, mais le second ne l'est pas. Le résultat final est "marie blabla apple hasblabla". Remarquez que le deuxième "a" est toujours là.
Qu'est-ce que je fais mal? :)
EDIT Is fonctionne maintenant. L'ajout du caractère de fin nul a corrigé le problème. Je sais que la chaîne résultante peut être supérieure à 100. C'est un devoir de l'école et je n'aurai pas de chaîne supérieure à 20 ou plus.
Pour commencer:
Cette ligne
strncpy(buffer, string, p-string);
pas nécessairement ajoute un 0
- terminator à ce qui avait été copié dans buffer
.
La ligne suivante
strcat(buffer, replace);
cependant, buffer
étant 0
- terminé.
Comme buffer
n’a pas été initialisé et que le 0
- terminator manque le plus probablement, cette dernière ligne peut très bien lire au-delà de la mémoire de buffer
et ainsi appeler le tristement célèbre comportement indéfini.
Il ne me semble pas clair quel algorithme vous essayez de suivre, cela me semble louche. Quelle est probablement l'approche la plus simple?
p
pour qu'il pointe juste après l'aiguillevoid str_replace(char *target, const char *needle, const char *replacement)
{
char buffer[1024] = { 0 };
char *insert_point = &buffer[0];
const char *tmp = target;
size_t needle_len = strlen(needle);
size_t repl_len = strlen(replacement);
while (1) {
const char *p = strstr(tmp, needle);
// walked past last occurrence of needle; copy remaining part
if (p == NULL) {
strcpy(insert_point, tmp);
break;
}
// copy part before needle
memcpy(insert_point, tmp, p - tmp);
insert_point += p - tmp;
// copy replacement string
memcpy(insert_point, replacement, repl_len);
insert_point += repl_len;
// adjust pointers, move on
tmp = p + needle_len;
}
// write altered string back to target
strcpy(target, buffer);
}
Attention: Vous devez également faire attention à la façon dont vous appelez votre fonction. Si la chaîne de remplacement est plus grande que l'aiguille, votre chaîne modifiée sera plus longue que celle d'origine. Vous devez donc vous assurer que la mémoire tampon d'origine est suffisamment longue pour contenir la chaîne modifiée. Par exemple.:
char s[1024] = "marie has apples has";
str_replace(s, "has", "blabla");
char *replace_str(char *str, char *orig, char *rep)
{
static char buffer[4096];
char *p;
int i=0;
while(str[i]){
if (!(p=strstr(str+i,orig))) return str;
strncpy(buffer+strlen(buffer),str+i,(p-str)-i);
buffer[p-str] = '\0';
strcat(buffer,rep);
printf("STR:%s\n",buffer);
i=(p-str)+strlen(orig);
}
return buffer;
}
int main(void)
{
char str[100],str1[50],str2[50];
printf("Enter a one line string..\n");
gets(str);
printf("Enter the sub string to be replaced..\n");
gets(str1);
printf("Enter the replacing string....\n");
gets(str2);
puts(replace_str(str, str1, str2));
return 0;
}
Entrée: marie a des pommes a
Sortie: marie blabla pommes blabla
int replace_str(char* i_str, char* i_orig, char* i_rep)
{
char l_before[2024];
char l_after[2024];
char* l_p;
int l_origLen;
l_origLen = strlen(i_orig);
while (l_p = strstr(i_str, i_orig)) {
sprintf(l_before ,"%.*s" ,l_p - i_str ,i_str);
sprintf(l_after ,"%s" ,l_p + l_origLen);
sprintf(i_str ,"%s%s%s" ,l_before ,i_rep ,l_after);
}
return(strlen(i_str));
}