0

I have to replace all the 'a' characters with "aaa" in a string.
So, what I'm trying to do. If the input is water, the output has to be like this: waaater.
I tried this:

#include <iostream>
#include <string.h>

using namespace std;

int main ()
{
  char s[100], t[100];
  int i;
  cout << "The string is: " << endl;
  cin.get (s, 100);
  strcpy (t, s);
  for (i = 0; i < strlen (s); i++)
    if (s[i] == 'a')
      strcat (strcpy (s + i, "aa"), t + i);
  cout << "The modified string  is: " << endl;
  cout << s;
}

but the output is Segmentation fault (core dumped).
I don't know what's wrong and I can't figure out what to change where.

paokv
  • 13
  • 1
  • 4
    Is there a reason that you cannot use `std::string` ?? – mathematician1975 Mar 14 '21 at 21:59
  • @mathematician1975 If I use ```std::string```, will it work? – paokv Mar 14 '21 at 22:04
  • If you *really* want to, you can do this with native arrays by using a reader and a writer. The writer to the target buffer advances once char per read from the reader buffer *unless* the char is an `a`, in which case it writes three times, advancing after each. Be sure to terminate the target string when done, and of course, limit check. – WhozCraig Mar 14 '21 at 22:07
  • 1
    What you're doing wrong is, each time through the loop you check the next letter of `s` and if you find an `a` you insert 2 more `a` into `s` but then the next letter in `s` is one that you just inserted so then you insert 2 more and then 2 more ... until you run out of space in s. To fix it, every time you insert into `s` you need to increase the index into `s` by 2 so you can get past what you just inserted - but you can't increase the index into `t` because you didn't insert anything into `t`. And that means you need two indexes: one for `s` and one for `t`: https://onlinegdb.com/r1Nuxzn7u – Jerry Jeremiah Mar 14 '21 at 22:43
  • If you want to see how to do it with std::string see https://stackoverflow.com/questions/1494399/how-do-i-search-find-and-replace-in-a-standard-string or https://stackoverflow.com/questions/20406744/how-to-find-and-replace-all-occurrences-of-a-substring-in-a-string – Jerry Jeremiah Mar 14 '21 at 22:48

3 Answers3

3

A simple regex would do it.

#include <iostream>
#include <regex>
#include <string>

int main() {
 std::string text = "water";
 std::regex replace("a");

 std::cout << std::regex_replace(text, replace, "aaa") << std::endl;

 return 0;
}

It replaces "water" with "waaater" as you wanted.

Varius
  • 469
  • 3
  • 17
1

You are trying to modify s in-place, but after each replacement of 'a' with "aaa", you are not skipping the new as you just inserted, so you end up replacing them as well, ie water -> waaater -> waaaaater -> waaaaaaater, and so on in an endless loop until an error occurs.

Try this instead:

#include <iostream>
#include <string.h>

using namespace std;

int main ()
{
    char s[100], t[100];
    int i, j;

    cout << "The string is: " << endl;
    cin.get (s, 100);

    strcpy (t, s);
    for (i = 0, j = 0; i < strlen (s); i++, j++) {
        if (s[i] == 'a') {
            strcat (strcpy (s + i, "aa"), t + j);
            i += 2;
        }
    }

    cout << "The modified string is: " << endl;
    cout << s;
}

Demo

Alternatively:

#include <iostream>
#include <string.h>

using namespace std;

int main ()
{
    char s[100];

    cout << "The string is: " << endl;
    cin.get(s, 100);

    int len = strlen(s);
    for (int i = 0; i < len; i++) {
        if (s[i] == 'a') {
            if ((len+3) > sizeof(s)) break; // no more space!
            memmove(s+(i+3), s+(i+1), sizeof(s)-(i+1));
            s[i+1] = 'a'; s[i+2] = 'a';
            i += 2;
            len += 2;
        }
    }

    cout << "The modified string is: " << endl;
    cout << s;
}

Demo

However, if you use std::string instead of char[], you can then use the std::string::find() and std::string::replace() methods, eg:

#include <iostream>
#include <string>

using namespace std;

int main ()
{
    string s;

    cout << "The string is: " << endl;
    cin >> s;

    string::size_type pos = 0;
    do {
        pos = s.find('a', pos);
        if (pos == string::npos) break;
        s.replace(pos, 1, "aaa");
        pos += 3;
    }
    while (true);

    cout << "The modified string is: " << endl;
    cout << s;
}

Demo

Alternatively, use std::string::insert() instead, eg:

#include <iostream>
#include <string>

using namespace std;

int main ()
{
    string s;

    cout << "The string is: " << endl;
    cin >> s;

    string::size_type pos = 0;
    do {
        pos = s.find('a', pos);
        if (pos == string::npos) break;
        s.insert(pos, "aa");
        // or: s.insert(pos, 2, 'a');
        pos += 3;
    }
    while (true);

    cout << "The modified string is: " << endl;
    cout << s;
}

Demo

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
0

Assume old_string = "water". It's length is 5. It has 1 'a'. Therefore, new_string should be of length new_length = old_length + (2 * number_of_a). In our case, 7. Declare a char array with size new_length + 1 (+1 for null char).

char new_string[8];

Set a variable j to 0. Now run a while loop from 0 to 7 inclusive with i being the loop variable. Inside the loop, first check if i equals 7. If YES, set new_string[i] = '\0'; ELSE, set new_string[i] = old_string[j]; Inside the same ELSE block, now check if old_string[j] == 'a' If YES, then increment i and set new_string[i] = old_string[j]; Perform the previous line one more time. Now, outside the ELSE block, increment j, increment i.

mindoverflow
  • 730
  • 4
  • 13