Замена символа в строке

Возможный дубликат:
Что такое функция для замены строки в C?

Я пытаюсь заменить определенный символ в моей строке несколькими символами. Вот пример того, что я пытаюсь сделать.

Скажем, у меня есть строка "ааабаа"

Я хочу заменить все вхождения символа "b" на 5 "c" s.

Поэтому, когда я закончу, "aaabaa" становится "aaacccccaa"

Я написал следующий код:

#include <stdio.h>
#include <string.h>
int main(void)
{
    char s[20] = "aaabaa";
    int i, j;
    for (i=0; s[i]!= '\0'; i++)
    {
        if (s[i] == 'b')
        {
            for (j=0; j<5; j++)
            {
                s[i+j] = 'c';
            }
        }
    }
    printf("%s\n", s);
}

Мой вывод из этой функции "aaaccccc". Похоже, что он просто перезаписывает последние два буквы "с". Есть ли какой-нибудь способ, которым я бы хотел, чтобы эти последние пару не перезаписывались?

7 ответов

Решение

Ваша проблема в том, что вы заменяете "ccccc" на исходную строку, перезаписывая оставшиеся символы после того, что хотите заменить... Вы должны скопировать в новую строку и отслеживать два индекса - по одному в каждом.

И будь счастлив, что ты объявил char s[20] больше, чем размер вашей исходной строки плюс значения замены, иначе вы бы создали уязвимость переполнения буфера в вашей критической системе входа в систему:-)

Ура,

Если вы хотите сделать это в целом, не беспокоясь о том, чтобы пытаться определить размер ваших буферов, вам следует malloc новая строка, достаточно большая, чтобы вместить результат:

/* return a new string with every instance of ch replaced by repl */
char *replace(const char *s, char ch, const char *repl) {
    int count = 0;
    const char *t;
    for(t=s; *t; t++)
        count += (*t == ch);

    size_t rlen = strlen(repl);
    char *res = malloc(strlen(s) + (rlen-1)*count + 1);
    char *ptr = res;
    for(t=s; *t; t++) {
        if(*t == ch) {
            memcpy(ptr, repl, rlen);
            ptr += rlen;
        } else {
            *ptr++ = *t;
        }
    }
    *ptr = 0;
    return res;
}

Использование:

int main() {
    char *s = replace("aaabaa", 'b', "ccccc");
    printf("%s\n", s);
    free(s);
    return 0;
}

Вы можете использовать другую переменную

#include <stdio.h>
#include <string.h>
int main(void)
{
    char s[20] = "aaabaa";
    char temp[20]="";
    int i, j,k;
    k=0;
    for (i=0; s[i]!= '\0'; i++)
    {
        if (s[i] == 'b')
        {
            for (j=0; j<5; j++)
            {
                temp[k] = 'c';
                k++;
            }
        }
        else
        {
            temp[k]=s[i];
            k++
        }
    }
    printf("%s\n", temp);
}

Необходимо объявить второй массив символов. В приведенном ниже коде он просто копирует содержимое массива s в s1, когда условие не выполняется.

#include <stdio.h>
#include <string.h>
int main(void)
{
  char s[20] = "aaabaa";
  char s1[1024];
  int i, j, n;
  for (i=0, n = 0; s[i]!= '\0'; i++)
  {
    if (s[i] == 'b')
    {
        for (j=0; j<5; j++)
        {
            s1[n] = 'c';
            n++;
        }
    }
    else
    {
        s1[n] = s[i];
        n++;
    }
}
s1[n] = '\0';
printf("%s\n", s1);
}
#include <stdio.h>
#include <string.h>

int main(void)
{
    char temp[20];
    char s[20] = "aaabaa";
    int i, j;
    for (i=0; s[i]!= '\0'; i++)
    {
        if (s[i] == 'b')
        {
            strcpy(temp,s[i+1]); //copy rest of the string in this case 'aa'
            for (j=0; j<5; j++)
            {
                s[i+j] = 'c';
            }
            s[i+j] = '\0';   // here we get s = "aaaccccc"
            strcat(s,temp); // concat rest of the string (temp = "aa") after job is done. 
                           //  to this point s becomes s = "aaacccccaa"
        }
    }
    printf("%s\n", s); //s = "aaacccccaa". 
}

здесь мы используем буфер (temp) для хранения оставшейся части строки после нашего заменяемого символа. после замены мы добавляем его до конца.

поэтому мы получаем s = "aaacccccaa"

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

Итак, вместо того, чтобы пытаться перезаписать символы в вашем цикле for, я бы предложил увеличить счетчик, который говорит вам, насколько большим должен быть ваш новый массив. Ваш счетчик должен начинаться с размера вашей исходной строки и увеличиваться на 4 каждый раз, когда обнаруживается экземпляр 'b'. После этого вы сможете написать функцию, которая соответствующим образом копирует измененную строку в новый символьный буфер размера [counter], вставляя 5 c каждый раз, когда обнаруживается a 'b'.

Используйте эту функцию:

char *replace(char *st, char *orig, char *repl) {
  static char buffer[4096];
  char *ch;
  if (!(ch = strstr(st, orig)))
   return st;
  strncpy(buffer, st, ch-st);  
  buffer[ch-st] = 0;
  sprintf(buffer+(ch-st), "%s%s", repl, ch+strlen(orig));
  return buffer;
  }

для вашего случая: printf("%s\n", replace(s,"b","ccccc"));

Другие вопросы по тегам