-1

How to delete all occurrences of FOO in a string s = FOOTHEFOOFOOBEST for example so the output would be THE BEST without any extra spaces unlike my code does.
Here is an sample of my try:

#include <iostream>
#include <string>
int main() {

    std::string s = "FOOTHEFOOFOOBEST";
        for (int i = 0; i < s.size(); i++){
            if (s[i] == 'F'&&s[i + 1] == 'O' && s[i + 2] == 'O'){
                std::cout << ' ';
                i += 2;
            }
            else
                std::cout << s[i];
        }

        return 0;
}

The output of my code is THE BEST there's an extra space however I expected THE BEST, Is there a simpler way to do that?

  • Do `std::sring::find()` in a loop until it returns `npos` – Slava Jun 04 '18 at 17:40
  • Can you use [regex](https://stackoverflow.com/questions/11508798/conditionally-replace-regex-matches-in-string#11509242)? – Nick Jun 04 '18 at 17:41
  • Note your code has UB as you may access out of bounds – Slava Jun 04 '18 at 17:41
  • There are two `FOO`s in the middle, so two spaces. You should also watch out for `i + 1` and `i + 2` not getting larger than `size()`. – Bo Persson Jun 04 '18 at 17:43
  • The undefined behavior in this code notwithstanding (you're breaching your allocated size in the tail of your search loop), track whether of not you have consecutive replacements and don't dump a space when it happens. That tracking state is set when you do a replacement, and cleared when you drop to the else-case. – WhozCraig Jun 04 '18 at 17:43
  • If you want to approach the problem is this way, you can always use a pointer, e.g. `char *p = (char *)s.c_str();` and then walk down the string, e.g. `while (*p) if (*p == 'F' && *(p + 1) == 'O' && *(p + 2) == 'O') { std::cout << ' '; p += 3; } else std::cout << *p++;`. Which is essentially the same. You can even use index notation `p[0] == 'F'`, etc.. instead of `*p`, if you like. – David C. Rankin Jun 04 '18 at 17:58

1 Answers1

0

I think I'd do it something like this:

#include <iostream>
#include <string>
#include <algorithm>
#include <iterator>

template<class Haystack, class Needle, class OutputIterator>
void separate(Haystack&& haystack, Needle&& needle, OutputIterator output_iter)
{
    const char* sep = "";

    auto first = std::begin(haystack);
    auto last = std::end(haystack);

    auto first_needle = std::begin(needle);
    auto last_needle = std::end(needle);
    auto needle_length = std::distance(first_needle, last_needle);

    while (first != last)
    {
        auto next = std::search(first, last, first_needle, last_needle);

        if (next == first)
        {
            first = std::next(first, needle_length);
        }
        else
        {
            std::cout << sep;
            std::copy(first, next, output_iter);
            sep = " ";
            first = next;
        }
    }
}

int main()
{
    using namespace std::literals;

    const auto needle = "FOO"s;

    const auto haystack = "FOOTHEFOOFOOBEST"s;

    separate(haystack, needle, std::ostream_iterator<char>(std::cout, ""));

    return 0;
}

expected output:

THE BEST
Richard Hodges
  • 68,278
  • 7
  • 90
  • 142