Erasing string values, string subscript out of range.

Mar 8, 2013 at 5:30pm
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?
Mar 8, 2013 at 5:36pm
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.
Mar 8, 2013 at 5:47pm
Also, you should use ++n only when a character isn't erased. Otherwise a character gets skipped and not tested.
Mar 8, 2013 at 5:47pm
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 Mar 8, 2013 at 5:49pm
Mar 8, 2013 at 5:55pm
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 Mar 8, 2013 at 6:05pm
Mar 8, 2013 at 6:03pm
Please read the previous responses.
Mar 8, 2013 at 6:03pm
If you only increment n when you did not call erase, there is no exclamation mark left: http://ideone.com/2AbBoY
Mar 8, 2013 at 6:13pm
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.