Что функция к строке замены в C?

Данный (char *) строка, я хочу найти все случаи подстроки и заменить их альтернативной строкой. Я не вижу простой функции, которая достигает этого в <string.h>.

83
задан a stone arachnid 28 July 2019 в 17:32
поделиться

6 ответов

Оптимизатор должен исключить большинство локальных переменных. Указатель tmp предназначен для того, чтобы strcpy не проходил строку, чтобы найти ноль. tmp указывает на конец результата после каждого вызова. (См. Алгоритм художника Шлемеля , почему strcpy может раздражать.)

// 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;
}
79
ответ дан 24 November 2019 в 08:53
поделиться

Вот пример кода, который это делает.

#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;
}
8
ответ дан 24 November 2019 в 08:53
поделиться

Вы может создать свою собственную функцию замены, используя strstr для поиска подстрок и strncpy для частичного копирования в новый буфер.

Если то, что вы хотите, чтобы replace_with было той же длины, что и то, что вы хотите, чтобы заменило , то, вероятно, лучше использовать новый буфер для копирования новой строки.

8
ответ дан 24 November 2019 в 08:53
поделиться

Поскольку строки в C не могут динамически расти, замена на месте обычно не работает. Поэтому вам нужно выделить место для новой строки, в которой достаточно места для вашей замены, а затем скопировать части из оригинала плюс замещение в новую строку. Для копирования деталей вы должны использовать strncpy .

8
ответ дан 24 November 2019 в 08:53
поделиться

Там нет ни одного.

Вы должны свернуть свои собственные, используя что-то вроде strstr и strcat или strcpy.

8
ответ дан 24 November 2019 в 08:53
поделиться

Это не предусмотрено в стандартной библиотеке C, поскольку, учитывая только символ *, вы не можете увеличить объем памяти, выделенной для строки, если замещающая строка длиннее замещаемой строки.

Вы можете сделать это проще, используя std :: string, но даже там, ни одна функция не сделает это за вас.

18
ответ дан 24 November 2019 в 08:53
поделиться
Другие вопросы по тегам:

Похожие вопросы: