Étant donné un ( char *
), je veux trouver toutes les occurrences d'une sous-chaîne et les remplacer par une autre chaîne. Je ne vois pas de fonction simple qui permette de réaliser cela dans <string.h>
.
Réponses
Trop de publicités?L'optimiseur devrait éliminer la plupart des variables locales. Le pointeur tmp est là pour s'assurer que strcpy n'a pas à parcourir la chaîne pour trouver le null. tmp pointe vers la fin du résultat après chaque appel. (Voir L'algorithme de Shlemiel le peintre pour savoir pourquoi strcpy peut être ennuyeux).
// You must free the result if result is non-NULL.
char *str_replace(char *orig, char *rep, char *with) {
char *result; // the return string
char *ins; // the next insert point
char *tmp; // varies
int len_rep; // length of rep (the string to remove)
int len_with; // length of with (the string to replace rep with)
int len_front; // distance between rep and end of last rep
int count; // number of replacements
// sanity checks and initialization
if (!orig || !rep)
return NULL;
len_rep = strlen(rep);
if (len_rep == 0)
return NULL; // empty rep causes infinite loop during count
if (!with)
with = "";
len_with = strlen(with);
// count the number of replacements needed
ins = orig;
for (count = 0; tmp = strstr(ins, rep); ++count) {
ins = tmp + len_rep;
}
tmp = result = malloc(strlen(orig) + (len_with - len_rep) * count + 1);
if (!result)
return NULL;
// first time through the loop, all the variable are set correctly
// from here on,
// tmp points to the end of the result string
// ins points to the next occurrence of rep in orig
// orig points to the remainder of orig after "end of rep"
while (count--) {
ins = strstr(orig, rep);
len_front = ins - orig;
tmp = strncpy(tmp, orig, len_front) + len_front;
tmp = strcpy(tmp, with) + len_with;
orig += len_front + len_rep; // move to next "end of rep"
}
strcpy(tmp, orig);
return result;
}
Cette fonction n'est pas fournie dans la bibliothèque C standard parce que, étant donné seulement un char*, vous ne pouvez pas augmenter la mémoire allouée à la chaîne si la chaîne de remplacement est plus longue que la chaîne remplacée.
Vous pouvez le faire en utilisant std::string plus facilement, mais même dans ce cas, aucune fonction unique ne le fera pour vous.
Il n'y en a pas.
Vous devez créer le vôtre en utilisant quelque chose comme strstr et strcat ou strcpy.
Vous pourriez construire votre propre fonction de remplacement en utilisant strstr pour trouver les sous-chaînes et strncpy pour copier les parties dans un nouveau tampon.
A moins que ce que vous voulez replace_with
est de la même longueur que ce que vous voulez replace
alors il est probablement préférable d'utiliser un nouveau tampon pour y copier la nouvelle chaîne.
Voici un exemple de code qui le fait.
#include <string.h>
#include <stdlib.h>
char * replace(
char const * const original,
char const * const pattern,
char const * const replacement
) {
size_t const replen = strlen(replacement);
size_t const patlen = strlen(pattern);
size_t const orilen = strlen(original);
size_t patcnt = 0;
const char * oriptr;
const char * patloc;
// find how many times the pattern occurs in the original string
for (oriptr = original; patloc = strstr(oriptr, pattern); oriptr = patloc + patlen)
{
patcnt++;
}
{
// allocate memory for the new string
size_t const retlen = orilen + patcnt * (replen - patlen);
char * const returned = (char *) malloc( sizeof(char) * (retlen + 1) );
if (returned != NULL)
{
// copy the original string,
// replacing all the instances of the pattern
char * retptr = returned;
for (oriptr = original; patloc = strstr(oriptr, pattern); oriptr = patloc + patlen)
{
size_t const skplen = patloc - oriptr;
// copy the section until the occurence of the pattern
strncpy(retptr, oriptr, skplen);
retptr += skplen;
// copy the replacement
strncpy(retptr, replacement, replen);
retptr += replen;
}
// copy the rest of the string.
strcpy(retptr, oriptr);
}
return returned;
}
}
#include <stdio.h>
int main(int argc, char * argv[])
{
if (argc != 4)
{
fprintf(stderr,"usage: %s <original text> <pattern> <replacement>\n", argv[0]);
exit(-1);
}
else
{
char * const newstr = replace(argv[1], argv[2], argv[3]);
if (newstr)
{
printf("%s\n", newstr);
free(newstr);
}
else
{
fprintf(stderr,"allocation error\n");
exit(-2);
}
}
return 0;
}
- Réponses précédentes
- Plus de réponses