3

Please tell me if I am understanding the the substr member function correctly?
result = result.substr(0, pos) + result.substr(pos + 1);
It takes the string from pos, 0 until (but not including), remove[i]
and then + result.substr(pos + 1); concatenates the rest of the string, except but not including the string / char in remove?

string removeLetters2(string text, string remove)
{
    int pos;
    string result = text;

    for (int i = 0; i < remove.length(); i++)
    {
        while (true)
        {
            pos = result.find(remove[i]);                
            if (pos == string::npos)                      
            {
                break;
            }
            else
            {
                result = result.substr(0, pos) +
                result.substr(pos + 1);
            }
        }
    }
    return result;
}
Moha the almighty camel
  • 4,327
  • 4
  • 30
  • 53
Tom Lilletveit
  • 1,872
  • 3
  • 31
  • 57
  • possible duplicate? : http://stackoverflow.com/questions/5891610/c-how-to-remove-characters-from-a-string – default Nov 07 '12 at 14:25

4 Answers4

7

In short, you are asking if

result = result.substr(0, pos) +
         result.substr(pos + 1);

removes the character at position pos, right?

Short Answer:

Yes.

Longer Answer:

The two-argument call takes the start index and the length (the one argument call goes to the end of string).

It helps to imagine the string like this:

F o o / B a r
0 1 2 3 4 5 6   <- indices

Now remove /:

F o o / B a r
0 1 2 3 4 5 6   <- indices
1 2 3 |         <- 1st length
      | 1 2 3   <- 2nd length

result = result.substr(0, 3)   <- from index 0 with length 3
       + result.substr(4);     <- from index 4 to end

As a programmer, always be aware of the difference between distance/index and length.

Better: If index is known:

Your code creates two new, temporary strings, which are then concatenated into a third temporary string, which is then copied to result.

It would be better to ask string to erase (wink wink) in place:

result.erase(pos,1);
// or by iterator
string::iterator it = ....;
result.erase(it,it+1);

This leaves more optimization freedom to the string implementer, who may choose to just move all characters after pos by one to the left. This could, in a specialized scenario, be implemented with a single assignment, a single loop, and within the loop with the x86 swap instruction.

Better: If characters to be deleted are known:

Or, but I am not sure if this gives better performance, but it may give better code, the algorithm remove_if:

#include <algorithm>

// this would remove all slashes, question marks and dots
....
    std::string foobar = "ab/d?...";
    std::remove_if (foobar.begin(), foobar.end(), [](char c) {
        return c=='/' || c=='?' || '.';
    });

remove_if accepts any function object.

If there is just one character, it gets easier:

// this would remove all slashes
std::remove (foobar.begin(), foobar.end(), '/');
Community
  • 1
  • 1
Sebastian Mach
  • 38,570
  • 8
  • 95
  • 130
4

Although the answer to your question is "yes", there is a better way to go about what you are trying to do. Use string::erase, like this:

result.erase(pos, 1);

This API is designed for removal of characters from the string; it achieves the same result much more efficiently.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
0

Yes, this function removes all letters in remove from text.

Angew is no longer proud of SO
  • 167,307
  • 17
  • 350
  • 455
0

since you seem to delete more than one type of character have a look at remove_if from <algorithm> with a special predicate too, although the response of dasblinkenlignt is the good one

PW.
  • 3,727
  • 32
  • 35