std:out_of_range when using string::erase

I was using a small code snippet to erase <em> from string doesn't work?

Code:
1
2
3
4
5
6
string htmlLine = "<em>suez</em> canal";
string searchEm = "<em>";
int posEmStart = static_cast<int>(htmlLine.find(searchEm));
int posEmEnd = static_cast<int>(posEmStart+searchEm.length());
int noOfSymbols = (posEmEnd-posEmStart)+1;
htmlLine.erase(posEmStart, noOfSymbols);


Throws this error:
terminate called after throwing an instance of 'std::out_of_range'
  what():  basic_string::erase
Aborted (core dumped)

What's wrong with the code?

Thanks
Seems ok.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <string>
#include <iostream>

int main()
{
        std::string htmlLine = "<em>suez</em> canal";
        std::string searchEm = "<em>";
        size_t posEmStart = htmlLine.find(searchEm);
        size_t posEmEnd = posEmStart+searchEm.length();
        size_t noOfSymbols = (posEmEnd-posEmStart)+1;

        std::cout << "posEmStart=" << posEmStart << std::endl;
        std::cout << "posEmEnd=" << posEmEnd << std::endl;
        std::cout << "noOfSymbols=" << noOfSymbols << std::endl;
        std::cout << "htmlLine.size()=" << htmlLine.size() << std::endl;

        htmlLine.erase(posEmStart, noOfSymbols);
        std::cout << "htmlLine=" << htmlLine << std::endl;
}


posEmStart=0
posEmEnd=4
noOfSymbols=5
htmlLine.size()=19
htmlLine=uez</em> canal
The above answer is correct, but just to let you know, to get noOfSymbols the plus one is not necessary. Since the .find(), gets the value of the position at the beginning of the search string.

In other words, .find(), will place the cursor right before <em>, like so : |<em>.

The .length(), will return the exact length of 4, which will cover the entire string of the tag.
Adding one will put it over by one making it take the character s into consideration, when you use the erase function.

An easier answer would be:
1
2
3
4
5
6
7
8
9
10
11
12
#include <iostream>
#include <string>
using namespace std;

int main()
{
     string htmlLine="<em>suez</em> canal";
     string searchEm="<em>";
     unsigned int length=searchEm.length();
     unsigned int startPos=htmlLine.find(startPos);
     htmlLine.erase(startPos, length);
}
Last edited on
1
2
3
string htmlLine = "<em>suez</em> canal";
string searchEm = "<em>"; // This will not be found because of the extra '/' in the above line.
int posEmStart = static_cast<int>(htmlLine.find(searchEm));


Several things to note in the above snippet. First static_casting the return value from the std::string::find() function is a problem, use the proper type for posEmStart, a size_t. When the find fails, as it is in this instance, the find() function returns the largest value that can be held in a size_t (std::string::npos). Trying to use this value (std::string::npos) for the "start" of the erase will cause an exception to be thrown. Before you try to use values from things like the find() function you should verify the number is not std::string::npos.

Thanks, now it works. And thanks @jib for the tip!
Topic archived. No new replies allowed.