Reputation: 115
stringstream str(line, ios_base::in);
while(!str.eof()){
string word;
str >> word;
std::transform(word.begin(), word.end(), word.begin(), ::tolower);
char c = *(--word.end());
char b = *word.begin();
if((c == ')' && b == '(') || (c == '\'' && b == '\'')){
word.erase(--word.end());
word.erase(word.begin()); //exception occurs here
}
c = *(--word.end());
if(c == ',' || c == '.' || c == '?' || c == '!')
word.erase(--word.end());
}
This code throws an std::length_error (what(): basic_string::_S_create) at word.erase(word.begin()); however if I change it to word.erase(0, 1); it works perfectly fine.
Why is that?
I am using gcc 4.8.1 (MinGW build)
Upvotes: 0
Views: 151
Reputation: 153810
There are multiple things wrong with your code:
std::istream::eof()
to terminate a loop does not work. You might want to use eof()
to decide whether you want to report an error.std::tolower()
with char
s on a platform where char
is signed result in undefined behavior, e.g., for most encodings it will result in undefined behavior when using it with my last name.word
is empty all kinds of strange things can happen. Since you didn't check if you could successfully read a word, I guess this is what happens: erase()
the position begin()
points to when using it on a empty string will fail.Upvotes: 2
Reputation: 523214
If the line
consists of a single character
'
then
(c == '\'' && b == '\'')
will pass, so we'll start to delete the beginning and end characters,word.erase(--word.end());
will remove the only character, making the string empty,word.erase(word.begin());
will crash, because word.begin()
now doesn't point to a valid character in the string. (I think it actually causes undefined behavior)Upvotes: 2