开发者

c++ string iterator

开发者 https://www.devze.com 2023-02-20 02:42 出处:网络
I\'m trying to do an if statement inside a loop with an iterator over a string, but can\'t figure out how to get the current character for the if statement:

I'm trying to do an if statement inside a loop with an iterator over a string, but can't figure out how to get the current character for the if statement:

for (std::string::iterator i=buffer.end()-1; i>=buffer.begin(); --i) {
    if (!isalpha(*i) && !isdigit(*i)) 开发者_如何转开发{
        if(i != "-") { // obviously this is wrong
            buffer.erase(i);
        }
    }
}

Can someone help me get the current character so I can do some additional if statements?


I can't figure out how to get the current character

You do it twice here:

if (!isalpha(*i) && !isdigit(*i))

When you dereference an iterator (*i), you get the element to which it points.

"-"

This is a string literal, not a character. Character constants use single quotes, e.g., '-'.

for (std::string::iterator i=buffer.end()-1; i>=buffer.begin(); --i)

This would be much simpler with reverse iterators:

for (std::string::reverse_iterator i = buffer.rbegin(); i != buffer.rend(); ++i)


if(i != "-")

should be

if(*i != '-')


To get the character just say *i, but this isn't enough. Your loop isn't legal because it's not allowed to decrement before begin. You should use reverse iterators or the remove_if algorithm.


Other answers have solved the particular issue that you have, but you should be aware that there are different approaches to solve your actual problem: erase elements that fullfill a condition. That can be easily solved with the remove/erase idiom:

// C++0x enabled compiler
str.erase( 
    std::remove_if( str.begin(), str.end(), 
                  [](char ch) { return !isalpha(ch) && !isdigit(ch) && ch != '-' } ),
    str.end() );

While this might look cumbersome at first, once you have seen it a couple of times it will no longer be surprising, and it is an effective way of deleting elements from a vector or string.

If your compiler does not have lambda support, then you can create a functor and pass it as the third argument to remove_if:

// at namespace level, sadly c++03 does not allow you to use local classes in templates
struct mycondition {
   bool operator()( char ch ) const {
      return !isalpha(ch) && !isdigit(ch) && ch != '-';
   }
};
// call:
str.erase( 
    std::remove_if( str.begin(), str.end(), mycondition() ),
    str.end() );


You have it right above in the previous if statement: i is an iterator, so *i gives the character referred to by the iterator.

Note that if you're going to iterate through a collection backwards, it's generally easier to use a reverse_iterator with rbegin and rend. I'd probably use a pre-packaged algorithm instead though.

0

精彩评论

暂无评论...
验证码 换一张
取 消