Icon Ressource

[C] Replace Funktionen - Ersetzung aller Vorkommen eines Teilstrings

Die folgende Replace Funktion führt eine einfache Stringersetzung durch, für Anwendungsfälle bei denen keine zeit- und rechenintensiven regulären Ausdrücke benötigt werden.
C:
#include <stdio.h>
#include <stdlib.h> // Replace
#include <string.h> // Replace

/** \brief  Sucht alle Vorkommen eines Teilstrings und ersetzt sie.
 * \param  str     Ursprünglicher String.
 * \param  search  Der zu suchende und zu ersetzende Teilstring.
 * \param  repl    Der String, der den gesuchten Teilstring ersetzt. (darf NULL sein)
 * \param  pLen    Pointer auf eine Variable vom Typ size_t, die die neue Länge zugewiesen bekommt. (darf NULL sein)
 * \return  Allokierter Puffer, der den geänderten String enthält.
 *          NULL wird zurückgegeben, wenn die Speicherallokation fehlgeschlagen ist
 *          oder wenn NULL an einen der ersten beiden Parameter übergeben wurde
 *          oder wenn search die Länge 0 hat. */
char *Replace(const char *const str, const char *const search, const char *const repl, size_t *const pLen)
{
  if (pLen)
    *pLen = 0U;

  if (!str || !search)
    return NULL;

  const size_t searchLen = strlen(search);
  if (!searchLen)
    return NULL;

  const size_t strLen = strlen(str),
               replLen = repl ? strlen(repl) : (size_t)0U;
  size_t currentLen = 0,
         capacity = ((strLen > replLen ? strLen : replLen) << 1) + 512U; // Aus Performancegründen werden mehr als 512 Bytes vorab allokiert.
  char *buf = NULL, *bufIt = NULL;
  if (!(buf = bufIt = (char*)malloc(capacity)))
    return NULL;

  const char *strIt = str;
  for (const char *found = NULL; (found = strstr(strIt, search));)
  {
    const size_t difLen = (size_t)(found - strIt);
    if (currentLen + difLen + replLen + 1U > capacity)
    {
      char *tmp = (char*)realloc(buf, (capacity <<= 1));
      if (!tmp)
      {
        free(buf);
        return NULL;
      }

      buf = tmp;
      bufIt = buf + currentLen;
    }

    bufIt = strcpy(strncpy(bufIt, strIt, difLen) + difLen, repl ? repl : "") + replLen;
    strIt = found + searchLen;
    currentLen += difLen + replLen;
  }

  const size_t total = currentLen + (size_t)(str + strLen - strIt) + 1U;
  if (total > capacity)
  {
    char *tmp = realloc(buf, total);
    if (!tmp)
    {
      free(buf);
      return NULL;
    }

    buf = tmp;
    bufIt = buf + currentLen;
  }

  strcpy(bufIt, strIt);
  if (pLen)
    *pLen = total - 1U;

  return buf;
}

int main(void)
{
  size_t length = 0;
  const char str[] = "xxx aaa xxx bbb xxx ccc xxx";

  char *updated = Replace(str, "xxx", "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ", &length); // Ersetzung von "xxx".
  if (!updated) return 1;
  printf("String:\n\"%s\"\nLaenge:\n%u\n\n", updated, (unsigned)length);
  free(updated);

  updated = Replace(str, "xxx", NULL, &length); // Eliminierung von "xxx".
  if (!updated) return 1;
  printf("String:\n\"%s\"\nLaenge:\n%u\n\n", updated, (unsigned)length);
  free(updated);

  updated = Replace(str, "foo", "bar", &length); // "foo" wird nicht gefunden, der zurückgegebene String ist somit eine Kopie des Originals.
  if (!updated) return 1;
  printf("String:\n\"%s\"\nLaenge:\n%u\n\n", updated, (unsigned)length);
  free(updated);

  return 0;
}

Ausgabe:
Code:
String:
"ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ aaa ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ bbb ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ ccc ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"
Laenge:
135

String:
" aaa  bbb  ccc "
Laenge:
15

String:
"xxx aaa xxx bbb xxx ccc xxx"
Laenge:
27
Autor
german
Aufrufe
991
Erstellt am
Letzte Bearbeitung
Bewertung
0,00 Stern(e) 0 Bewertung(en)

Weitere Ressourcen von german

Oben Unten