help understanding std::string erase

Hello, i have been looking at strings and im curious why the code snippet attached doesnt remove all the punctuations in string a!..
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>
#include <cctype>
#include <cmath>

using namespace std;

int main()
{
    string a = "eix!@#$%^&*()_+%if";

    for ( unsigned i = 0; i < a.length(); i++)
    {
        if ( ispunct(a[i]))
        {
            a.erase(a.begin() + i);
        }
    }

    cout << a;
}


Thanks;
If you find a punctuation character, you erase it. That's fine, but what happens is the next character is moved into the position you just erased. If the next character is also punctuation, you going to skip over it because your for loop is going increment i so the next iteration will look at the character after the one that was just moved into the erased position.

It's better to use a while loop for this kind of scanning. You only want to increment i when you find a character that is not punctuation.
Thanks for the reply...

why does it work if i change the for loop to this form

1
2
3
4
5
6
7
    for ( unsigned i = 0; i < _word.length(); i++)
    {
        if ( ispunct(_word[i]))
        {
            _word.erase(i--,1);
        }
    }


what does this do or mean

 
erase(i--,1);
It's best to use the erase-remove idiom. http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Erase-Remove

1
2
3
4
5
6
7
8
9
10
11
12
13
#include <iostream>
#include <string>
#include <algorithm>
#include <cctype>

int main()
{
    std::string a = "!!eix!@#$%fghjk^&*()_+%if***" ;
    std::cout << a << '\n' ;

    a.erase( std::remove_if( a.begin(), a.end(), []( char c ) { return std::ispunct(c); } ), a.end() ) ;
    std::cout << a << '\n' ;
}

http://coliru.stacked-crooked.com/a/4f37593caf401f19
what does this do or mean
 
  erase(i--,1); 

It erases the i'th character for a length of 1, then decrements i. This accounts for the fact the i is incremented regardless of whether you found a punctuation character or not. As I pointed out above, you want to increment i only when you don't find a punctuation character. By decrementing it, you're essentially not incrementing i for that iteration of the for loop.
Last edited on
Thanks a ton :).
Topic archived. No new replies allowed.