1

I am given a string and I have to remove a substring from it. Namely WUB, and replace it with a space character.

There are 2 WUB's between ÁRE' and 'THE'. SO the first condition in if statement is for not printing two blank spaces but on executing the code two blank spaces are being printed.

Input:  WUBWEWUBAREWUBWUBTHEWUBCHAMPIONSWUBMYWUBFRIENDWUB
Output: WE ARE THE CHAMPIONS MY FRIEND 

Here is my code so far:

#include <iostream>

using namespace std;

int main()
{
    const string check = "WUB";
    string s, p;
    int ct = 0;
    cin >> s;

    for (int i = 0; i < s.size(); i++)
    {
        if (s[i] == 'W' && s[i+1] == 'U' && s[i+2] == 'B')
        {
            i += 2;
            if (p[ct] == '32' || p.empty())
            {
                continue;
            }
            else
            {
                p += ' ';
                ct++;
            }
        }
        else
        {
            p += s[i];
            ct++;
        }
    }

    cout << p;
    return 0;
}

Why is the first if statement never executed?

ΦXocę 웃 Пepeúpa ツ
  • 47,427
  • 17
  • 69
  • 97
logan007
  • 67
  • 1
  • 10
  • What makes you think that the compiler is skipping it? What do you see when debugging the code? – UnholySheep Aug 31 '20 at 08:11
  • 4
    `s[i+1]` and `s[i+2]` will be out of bounds when `i == s.size() - 1` and `i == s.size() - 2` (the last and second to last iterations of your loop). – Some programmer dude Aug 31 '20 at 08:11
  • 3
    And `'32'` is a multi-character constant, and those are implementation specific in how they work. Do you mean `p[ct] == 32` (the *integer* constant `32`), or rather `p[ct] == ' '` to check for a single space (or perhaps `std::isspace(p[ct])` to check for any space)? – Some programmer dude Aug 31 '20 at 08:13
  • 2
    By the way, since `p` starts out empty, then there's a risk that `p[ct]` is also out of bounds. Actually, since you append characters in lock-step with increasing `ct`, then `ct` will always be equal to `p.size()`, so `ct` will *always* be out of bounds. – Some programmer dude Aug 31 '20 at 08:16

4 Answers4

3

This condition

if(p[ct]=='32')

should read either

if(p[ct]==32)

or

if(p[ct]==' ')

that is, compare to the numeric value of the space character or to the space character itself.

Additionally, when your i grows close to the string's length, the subexpressions s[i+1] and s[i+2] may reach non-exiting characters of the string. You should continue looping with a i<s.length()-2 condition.

EDIT

For a full solution you need to fully understand the problem you want to solve. The problem statement is a bit vague:

remove a substring ("WUB") from (a given string). And put a space inplace of it if required.

You considered the last condition, but not deeply enough. What does it mean, 'if required'? Replacement is not required if the resulting string is empty or you appended a space to it already (when you encounter a second of further consecutive WUB). It is also not necessary if you are at WUB, but there is nothing more following it - except possibly another WUBs...

So, when you find a "WUB" substring it is too early to decide if a space is needed. You know you need a space when you find a non-WUB text following some WUB (or WUBs) and there was some text before those WUB(s).

CiaPan
  • 9,381
  • 2
  • 21
  • 35
  • Or you can use `if(std::isspace(p[ct]))`. – Lukas-T Aug 31 '20 at 08:17
  • I looked after the out of bounds condition but still the first if statement is getting ignored. – logan007 Aug 31 '20 at 08:20
  • @logan007 Did you also fix _this_ bug? How do you know it's ignored? I can't repdroduce your problem after fixing the two errors. – Lukas-T Aug 31 '20 at 08:26
  • @churill If you see there are 2 WUB's between ÁRE' and 'THE'. SO my if statement was for not printing two blank spaces but even after fixing the bugs you'll notice that actually two blank spaces are being printed. – logan007 Aug 31 '20 at 08:29
  • @logan007 That's true, you might want to edit your question to be more clear about the problem you are facing. See Some programmer dude's comment if you want to know what's wrong. – Lukas-T Aug 31 '20 at 08:34
  • @logan007 Please see the expanded answer. – CiaPan Aug 31 '20 at 10:10
3

2 things are going to break your code:

  1. you are doing a for loop like this int i=0;i<s.size() but reading (s[i]=='W' && s[i+1]=='U' && s[i+2]=='B')
  2. and here: if(p[ct]=='32') you mean for sure if(p[ct]==32) or if(p[ct]==' ')
ΦXocę 웃 Пepeúpa ツ
  • 47,427
  • 17
  • 69
  • 97
1

There are actually three bugs here, so it's probably worth to conclude them in one answer:

  1. The first condition:

    if (s[i] == 'W' && s[i+1] == 'U' && s[i+2] == 'B')
    

    is out of bounds for the last two characters. One fix would be to check the length first:

    if(i < s.length() - 2 && s[i] == 'W' && s[i+1] == 'U' && s[i+2] == 'B')
    
  2. There's a multicharacter-literal in

    if (p[ct] == '32' || p.empty())  
    

    Use ' ' or 32 or std::isspace instead. IMO the last one is the best.

  3. In the same condition

    p[ct] == '32' 
    

    is always out of bounds: ct is equal to p.length(). (Credits to Some programmer dude, who mentioned this in the comments!) The variable ct is also redundant, since std::string knows it's length. I suggest to use std::string::back() to access the last character and reorder the condition as so:

    if (p.empty() || std::isspace(p.back()))  
    
Lukas-T
  • 11,133
  • 3
  • 20
  • 30
0

The algorithm to this program is on the right track.

However, there is a few issues..

  1. The for loop goes out of index. A way to solve this issue is substracting the size -3. Something like this.

    for (int i=0; i<s.size()-3; i++) { }

  2. I do not suggest using other variables as counters like ct. In this case ct can reach an index out of bound error by using p[ct] inside the for loop. Creating a string and using append() function will be a better solution. In this case, we iterate through each character in the string and if we find "WUB" then we append a " ". Otherwise, we append the character.

  3. I highly recommend to write the first if() statement using substring() from C++. This makes the code easier to read.

Substring creates and returns a new string that starts from a specific position to an ending position. Here is the syntax

syntax: substr(startingIndex, endingIndex); endingIndex is exclusive

#include <string>
#include <iostream>

int main() {
   string s, p;
   cin >> s;
   for(int i=0;i<s.size()-3;i++) {
      if (s.substr(i, i+3) == "WUB") {
         p.append(" ");
      } else {
         p.append(s.substr(i,i+1));
         i++;
         continue;
      }
      i+=3;
   }
}