¿Qué función es reemplazar una subcadena de una cadena en C?

Resuelto asked hace 15 años • 0 respuestas

Dada una char *cadena (), quiero encontrar todas las apariciones de una subcadena y reemplazarlas con una cadena alternativa. No veo ninguna función simple que logre esto en <string.h>.

 avatar Apr 23 '09 07:04
Aceptado

El optimizador debería eliminar la mayoría de las variables locales. El puntero tmp está ahí para garantizar que strcpy no tenga que recorrer la cadena para encontrar el valor nulo. tmp apunta al final del resultado después de cada llamada. (Consulte el algoritmo del pintor Shlemiel para saber por qué strcpy puede ser molesto).

// 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;
}
jmucchiello avatar Apr 23 '2009 01:04 jmucchiello

Esto no se proporciona en la biblioteca C estándar porque, dado solo un carácter*, no se puede aumentar la memoria asignada a la cadena si la cadena de reemplazo es más larga que la cadena que se reemplaza.

Puedes hacer esto usando std::string más fácilmente, pero incluso allí, ninguna función lo hará por ti.

Don Neufeld avatar Apr 23 '2009 00:04 Don Neufeld