Why doesn't this work ??

Try this please:

for(string::iterator i=str.begin();i!=str.end();i++)
    if(*i==' ')
        str.erase(i);

what happens is that when the iterator reaches the space character in the string, it just exits the loop!, it doesn't even execute the conditional check, it just exits as if it reached the end of the string.
Help me out with this
Thank you
LVL 1
gamesdevAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

tinchosCommented:
Could you post the full function so as to check it out

It seems right to me
0
MeiaDoseCommented:
The following code works...it executes de erase method and continues searching for other spaces...
"
void main(){
      string str="ABC DEF GHI";
      for(string::iterator i=str.begin();i!=str.end();i++)
              if(*i==' ')
                    str.erase(i);
}
"

Post your code please.



0
mtmikeCommented:
Code should work unless you're using an old std::string that only supports the two argument erase method. In that case, erase would delete everything up to the rest of the string.

See, for example:
http://www.msoe.edu/eecs/cese/resources/stl/string.htm
0
HTML5 and CSS3 Fundamentals

Build a website from the ground up by first learning the fundamentals of HTML5 and CSS3, the two popular programming languages used to present content online. HTML deals with fonts, colors, graphics, and hyperlinks, while CSS describes how HTML elements are to be displayed.

YuriPutivskyCommented:
std::string is a vector container the correct code should look like
for(string::iterator i=str.begin(); i!=str.end(); )
    if(*i==' ')
        i = str.erase(i);
    else
        ++i;

0
rstaveleyCommented:
You seem to get away with that code on the two implementations I've just tested. However, if you have a trailing ' ' in the string, you'd expect it to go kaboom (and sure enough it does), because the iterator is already at str.end() on the final erase before the iterators is incremented.

All in all it looks a bit implementation-specific, expecting the iterator to continue to be usable after an erase. Another expert will be able to quote you chapter and verse when you can legally expect to continue to use an interator, but I get alarm bells when a container is resized.

I'd play it safe with the following:

--------8<--------
#include <iostream>
#include <string>

int main()
{
        std::string str = "abc def ghi ";
        for (std::string::iterator i = str.begin();i != str.end();++i)
                if (*i == ' ') {
                        str.erase(i);
                        i = str.begin(); // Play it safe and start from the beginning again
                }

        std::cout << str << '\n';
}
--------8<--------
0
rstaveleyCommented:
> that code

by which I mean MeiaDose's test code, which doesn't have a trailing space.
0
MeiaDoseCommented:
Got to give it up to rstaveley!

Nice post!

MeiaDose
0
rstaveleyCommented:
Not that great, actually, mine still goes kaboom if str = " ", unlike YuriPutivsky's code :-(

This is better... (continuing with my paranoia about resizing the container) :

--------8<--------
#include <iostream>
#include <string>

int main()
{
        std::string str = "abc def ghi ";
        for (std::string::iterator i = str.begin();i != str.end();)
                if (*i == ' ') {
                        str.erase(i);
                        i = str.begin(); // Play it safe and start from the beginning again
                }
                else
                        ++i;

        std::cout << str << '\n';
}
--------8<--------
0
MeiaDoseCommented:
hmmmm interesting...

I've just teste my code and it doesnd have any problem.

I've used these strings:

string a= "  "; // Only spaces

and

strinb b = " a ";

And the code work's great...what do you mean by "the code goes kaboom!". I like that expression though! lol :)
0
MeiaDoseCommented:
So for the record:

The erase method returns an iterator addressing the first character after the last character removed by the member function.

So you can do this:
"
void main(){
      string str=" a ";

      for(string::iterator i=str.begin();i!=str.end();i++)
            if(*i==' ')
                  i=str.erase(i);// Update the pointer position!

      cout<<str;
}
"
0
_ys_Commented:
You don't even need to use a for loop - why recreate the wheel.

// We utilise equal_to and bind2nd
#include <functional>

// We utilise remove_if
#include <algorithm>

std::string str = "abc def ghi ";
std::string::iterator begin = str.begin ( ), end = str.end ( );

//Remove those peaky spaces
std::string::iterator new_end = remove_if ( begin, end, bind2nd (equal_to<char>( ), ' ' ));

if (new_end != end)
    str.erase (new_end, end);
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
rstaveleyCommented:
Nice R-ing of TFM, MeiaDose, but you've fallen into the trap of incrementing the pointer again and you'd kaboom on a trailing space :-)

_ys_'s solution is of course the best one!

However.... if gamesdev wants to go along with his original approach with the combined stuggles to correct it by rstaveley and MeiaDose he should go with:
--------8<--------
#include <iostream>
#include <string>

int main()
{
        std::string str = "abc def ghi ";
        for (std::string::iterator i = str.begin();i != str.end();)
                if (*i == ' ')
                        i = str.erase(i);
                else
                        ++i;

        std::cout << str << '\n';
}
--------8<--------

Prior to seeing _ys_'s solution, I'd have recommended generating a copy like this:
--------8<--------
#include <iostream>
#include <string>

int main()
{
        using std::string;
        string src = " ta ra ma sa la ta ";
        string dst;
        typedef string::const_iterator citr;
        for (citr i = src.begin();i != src.end();++i)
                if (*i != ' ')
                        dst.push_back(*i);
        std::cout << "I like \"" << dst << "\"\n";
}
--------8<--------

If there is a virtue to the copy approach above, its allowing yourself to get away with less knowledge of library functions! That's probably not a real virtue though.

I was looking at a copy_if approach with bind2nd(equal_to<char>( ),' '), but the STL copy_if function doesn't seem to have made it to the C++ standard... and it required an insert iterator, which is something you can't get from basic_string anyhow.

Nice one _ys_!
0
_ys_Commented:
Thanks rstaveley.

I would normally not divert any from code in the original post, as it usually part of a bigger scheme of things. But in this case, I just had to.

>> the combined stuggles to correct it by rstaveley and MeiaDose
lol - Reference to oneself in the third person.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C++

From novice to tech pro — start learning today.