6

Possible Duplicate:
What is the function to replace string in C?

I am trying to replace a certain character in my string with multiple characters. Here is an example of what I am trying to do.

Say I have the string "aaabaa"

I want to replace all occurrences of the character "b" with 5 "c"s.

So when I am done, "aaabaa" becomes "aaacccccaa"

I have written the following code:

#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);
}

My output from this function is "aaaccccc". It appears that it just overwrites the last two a's with the c's. Is there any way I would have it so that these last couple of a's dont get overwritten?

Community
  • 1
  • 1
me45
  • 1,059
  • 3
  • 14
  • 16
  • you need [`memmove()`](http://www.cplusplus.com/reference/clibrary/cstring/memmove/) – Agnius Vasiliauskas Oct 15 '12 at 06:00
  • 1
    lets just for a moment assume *every* char in the string is a 'b'... your target buffer better be 5x longer than the string that is occupying it at the time of invoke. At a minimum if you want this done *in-place* you *need* to code the algorithm to account for the size of the *buffer* (not just the string) occupied by the content undergoing substitution. Not doing so is eventually a recipe for disaster. – WhozCraig Oct 15 '12 at 06:05

7 Answers7

11

If you want to do this in general, without worrying about trying to size your buffers, you should malloc a new string just large enough to hold the result:

/* 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;
}

Usage:

int main() {
    char *s = replace("aaabaa", 'b', "ccccc");
    printf("%s\n", s);
    free(s);
    return 0;
}
nneonneo
  • 171,345
  • 36
  • 312
  • 383
5

Your problem is that you replace the "ccccc" into the original string thus overwriting the remaining characters after what you wish to replace... You should copy into a new string and keep track of two indices - one in each.

And be happy that you declared char s[20] larger than the size of your original string plus the replace values, as otherwise you'd have created a buffer overflow vulnerability in your critical login system :-)

Cheers,

Anders R. Bystrup
  • 15,729
  • 10
  • 59
  • 55
1

It is necessary to declare a second char array. In below code it just copies content of array s to s1 when condition fails.

#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);
}
Riskhan
  • 4,434
  • 12
  • 50
  • 76
1

You can use a different variable

#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);
}
Bhavik Shah
  • 5,125
  • 3
  • 23
  • 40
1
#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". 
}

here we are using a buffer (temp) to store the rest of the string after our to be replaced character. after the replacement is done we append it to the end.

so we get s = "aaacccccaa"

VishalDevgire
  • 4,232
  • 10
  • 33
  • 59
0

Well, if you're going to dynamically allocate the array, you will probably have to allocate a second array. This is necessary because your string s only has a fixed amount of memory allocated.

So, instead of tryig to overwrite the characters in your for loop, I would suggest incrementing a counter that told you how big your new array has to be. Your counter should start off as the size of your original string and increment by 4 each time an instance of 'b' is found. You should then be able to write a function that appropriately copies the modified string over to a new char buffer of size[counter], inserting 5 c's every time a 'b' is being found.

-1

Use this function :

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;
  }

for your case : printf("%s\n", replace(s,"b","ccccc"));

Ta Duy Anh
  • 1,478
  • 9
  • 16