GameX
GameX

Reputation: 67

Removing specific words from a string input

In the required code , I have to input a string and output that string after removing all occurences of a given word in that string. Example: Say I wish to remove WUB from the string.

Input1: WUBWUBABCWUB

Output1:ABC

Input2:WUBWEWUBAREWUBWUBTHEWUBCHAMPIONSWUBMYWUBFRIENDWUB

Output2:WE ARE THE CHAMPIONS MY FRIEND

Here is my code:

#include <bits/stdc++.h>

using namespace std;

int main()
{
    string in;
    cin>>in;                           //input
    int n=in.length();

    int pos =in.find("WUB");
    for(;pos!=-1;){
            pos =in.find("WUB");
        if(pos!=-1){                //manipulating string by erasing and inserting spaces between words
            in.insert(pos+3," ");
            in.erase(pos,pos+3);
            }
    }
            if(in[0]==' ')
                in.erase(in.begin());
            if(in[n-1]==' ')                      //removing extra spaces
                in.erase(in.end());
    cout<<in;
}

It works for input 1, but for input 2 gives wrong output. Output2:WEETHEONSND

What is wrong here?

Upvotes: 0

Views: 119

Answers (3)

O Yahya
O Yahya

Reputation: 376

You can create more efficient and neat code by using Regex to find the unwanted words, and then replace them with a space. Of course you will then have to use unique() to remove the double spaces.

Code

#include <iostream>
#include <regex>

bool BothAreSpaces(char lhs, char rhs)
{
    return (lhs == rhs) && (lhs == ' ');
}

int main()
{
    string s("WUBWEWUBAREWUBWUBTHEWUBCHAMPIONSWUBMYWUBFRIENDWUB"); //Input string
    regex e("(WUB)");   // Regex syntax to filtr unwanted string
    string result; //Filtered string


    regex_replace(std::back_inserter(result), s.begin(), s.end(), e, " "); //Replace unwanted word with space
    string::iterator new_end = unique(result.begin(), result.end(), BothAreSpaces); //Find double spaces
    result.erase(new_end, result.end()); //Remove double spaces
    cout << result << endl;
}

Output

WE ARE THE CHAMPIONS MY FRIEND

Upvotes: 1

Vlad from Moscow
Vlad from Moscow

Reputation: 310990

Instead of two sequential calls of the function insert and erase you could use only one call of the function replace.

Moreover this call of member function earse

in.erase(pos,pos+3);

The second argument shall specify the number of characters that need to be erased.

Also it seems you need to remove all leading and trailing blanks instead of only one blank from the both sides.

        if(in[0]==' ')
            in.erase(in.begin());
        if(in[n-1]==' ')                      //removing extra spaces
            in.erase(in.end());

The program can look the following way

#include <iostream>
#include <string>
#include <limits>

int main() 
{
    while ( true )
    {
        std::cout << "Enter the source string (Enter - exit): ";

        std::string s;

        if ( not std::getline( std::cin, s ) or s.empty() ) break;

        std::cout << "Enter the substring to remove: ";

        std::string t;

        std::cin >> t;
        std::cin.ignore( std::numeric_limits<std::streamsize>::max(), '\n' );

        if ( not t.empty() )
        {
            for ( auto pos = s.find( t ); 
                  pos != std::string::npos;
                  pos = s.find( t, pos ) )
            {
                s.replace( pos, t.size(), 1, ' ' );
                ++pos;
            }                 
        }

        s.erase( 0, s.find_first_not_of( " \t " ) );
        auto pos = s.find_last_not_of( " \t " ); 
        if ( pos != std::string::npos ) s.erase( ++pos );

        std::cout << "The source string: \"" << s << "\"\n";
    }

    return 0;
}

Its output might look like

Enter the source string (Enter - exit): WUBWUBABCWUB
Enter the substring to remove: WUB
The source string: "ABC"
Enter the source string (Enter - exit): WUBWEWUBAREWUBWUBTHEWUBCHAMPIONSWUBMYWUBFRIENDWUB
Enter the substring to remove: WUB
The source string: "WE ARE  THE CHAMPIONS MY FRIEND"
Enter the source string (Enter - exit): 

Upvotes: 1

Botje
Botje

Reputation: 30840

The overload of string::erase you use is

basic_string& erase( size_type index = 0, size_type count = npos );

You are passing pos+3 as count, instead of just 3.

Upvotes: 2

Related Questions