Как заменить подстроки в массиве - PullRequest
0 голосов
/ 18 апреля 2019

У меня есть программа, которая заменяет части массива char содержимым другого, однако она также заменяет части массива, которые не следует заменять.

Код ниже является кодом, отвечающим за замену символов в массиве. Однако по одному символу за раз, когда только часть того, что предполагается заменить, находится в массиве, подобном xy из xyz, он должен оставить это в покое и искать следующее вхождение xyz, которое он затем заменит.

i =0;
while(i < 30){
    j=0;
    while(j < k){
        if(carray[i] == aarray[j])
            carray[i] = barray[j];
        j++;
    }
    i++;
}

Моя проблема в том, что если присутствует только часть того, что программа должна искать и заменять, она заменяет ее, даже если это не полное слово, которое подразумевалось.

например:

если я хочу заменить xyz на abc в массиве xyzdefxyzghixy тогда массивы имеют следующее содержимое:

aarray[] = {xyz}
barray[] = {abc}
carray[] = {xyzdefxyzghixy}

Я получаю abcdefabcghiab в качестве вывода, и последние два символа ab должны фактически остаться xy


т.е. * * тысяча тридцать три

Я ожидаю, что результат будет abcdefabcghixy

что я тут не так сделал.

Примечание: обратите внимание, что я хочу использовать только stdio.h

Вся помощь очень ценится.

Заранее спасибо.

1 Ответ

1 голос
/ 19 апреля 2019

Заменить нужно только тогда, когда вы найдете полную подстроку.

Есть полезные стандартные функции:

  • strstr позволяет найти подстроку в строке
  • memcpy может использоваться для замены старой подстроки новой

Предложение:

#include <stdio.h>
#include <string.h>

int main(int argc, char ** argv)
{
  if (argc != 4)
    printf("usage : %s <str> <old> <new>\n", *argv);
  else {
    char * old = argv[2];
    char * new = argv[3];
    size_t len = strlen(old);

    if (len != strlen(new))
      fprintf(stderr, "'%s' and '%s' do not have the same length\n", old, new);
    else {
      char * str = argv[1];
      char * p = str;

      printf("'%s' -> ", str);

      /* the loop doing the replacements */
      while ((p = strstr(p, old)) != NULL) {
        memcpy(p, new, len);
        p += len;
      }

      printf("'%s'\n", str);
    }
  }

  return 0;
}

Компиляция и исполнение:

pi@raspberrypi:/tmp $ gcc -pedantic -Wextra -Wall r.c
pi@raspberrypi:/tmp $ ./a.out
usage : ./a.out <str> <old> <new>
pi@raspberrypi:/tmp $ ./a.out xyzdefxyzghixy xyz abc
'xyzdefxyzghixy' -> 'abcdefabcghixy'

Редактировать

Примечание: обратите внимание, что я хочу использовать только stdio.h

Может быть:

#include <stdio.h>

int main(int argc, char ** argv)
{
  if (argc != 4)
    printf("usage : %s <str> <old> <new>\n", *argv);
  else {
    char * old = argv[2];
    char * new = argv[3];
    char * str = argv[1];

    /* check old and new have the same length */
    char * pold, * pnew;

    for (pold = old, pnew = new; *pold && *pnew; ++pold, ++pnew)
      ;

    if (*pold || *pnew)
      fprintf(stderr, "'%s' and '%s' do not have the same length\n", old, new);
    else {
      printf("'%s' -> ", str);

      char * pstr = str;

      /* the loop doing the replacements */
      while (*pstr) {
        /* check if substring */
        char * pold = old;
        char * psubstr = pstr;

        while (*pold && (*pold == *psubstr)) {
          pold += 1;
          psubstr += 1;
        }

        if (*pold == 0) {
          /* substring, replacement */
          pnew = new;

          while (*pnew)
            *pstr++ = *pnew++;
        }
        else
          pstr += 1;
      }

      printf("'%s'\n", str);
    }
  }

  return 0;
}

Как вы видите, это плохой выбор, очень легко понять, что делает предыдущая версия, это не так с этой версией

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...