Erasing string values, string subscript out of range.

Hey people. I don't quite understand how I'm getting the error,

Expression: string subcript out of range.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <iostream>
#include <string>
using std::string;
using std::cin;
using std::cout; using std::endl;

int main() // Erasing punctuations from string.
{
	string input ("Hello, World!!!");

	decltype (input.size()) n = 0;

	while (n != input.size())
	{
	        if (ispunct(input[n]))
		{
			input.erase (n,1);
		}
	
		++n;
		cout << input << endl;
	}
	return 0;
}


Can someone explain the problem to me please?
When you erase a character and increment n, the difference between the size and n changes by two, so you are skipping over when n == size. Try using n < size instead.
Also, you should use ++n only when a character isn't erased. Otherwise a character gets skipped and not tested.
To make this work, increment n only when you don't call erase. Otherwise, let it stay where it was: after you delete the 5th character (comma), you want n to stay 5 to point at what used to be 6th and is now 5th character, the space.

Incidentally, why a loop instead of erase-remove?

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

int main()
{
    std::string input("Hello, World!!!");
    input.erase( std::remove_if(input.begin(), input.end(),
                              [](char c){return ispunct(c);}),
                 input.end());
    std::cout << input << '\n';
}


(or just erase_all() from boost string algorithm library)

Last edited on
Thanks for the quick response, I think I get it now. At one point n became bigger than size and prompted the error right?

The thing is, there's one exclamation mark left at the end. Is there a way to remove it all out?

Edit: Whoops didn't see previous posts.
Last edited on
Please read the previous responses.
If you only increment n when you did not call erase, there is no exclamation mark left: http://ideone.com/2AbBoY
Thanks Chervil and Cubbi, it's working fine now =). I included this as the condition for ++n;.

1
2
3
4
if (!ispunct(input[n]))
{
	++n;
}


I'm studying from C++ Primer Cubbi, so I didn't know about erase-remove. Also I'm trying to keep with the book's structure, so didn't even think about using boost. The code you posted is over my head at the moment, many thanks though I'll be saving it.
Topic archived. No new replies allowed.