Need help how to make a remove_if function to "remove_if_not"

So after trying to solve a problem for several hours i am very close. I need to remove all characters that is not alphabetical but currently i am removing all alphabetical characters and keeping everything else.

This is the piece of code that currently removes all alphabetical characters instead of removing all other characters except the alphabetical. Please help me make this a "remove_if_not" function. I have no idea where to start after experimenting a lot.

 
tempbook.erase(remove_if(tempbook.begin(), tempbook.end(), ::isalnum), tempbook.end());
Last edited on
Create another function that does the 'not' with isalnum(...) and pass that function.
Yeah i have no idea how to do that. I am new to c++ and need explaining as if i am 3 years old.

Thanks.
Last edited on
1
2
3
func notisalnum (para)
return !isalnum(para);
end func
Last edited on
I am sorry but i have been sitting with this for so long time and i have no idea what do.


I have been working with c++ for only a couple of days so EVERYTHING is a question-mark for me.

Something like this?
1
2
3
4
5
6
void NotAlphaNum ()
{
  return !::isalnum;
}

tempbook.erase(remove_if(tempbook.begin(), tempbook.end(), NotAlphaNum()), tempbook.end());


I did not get this to work. I am at a loss here. been sitting with code for 12hours so i cant really think anymore heh.
isalnum takes in a parameter. notalphanum should do the same.
NotAlphaNum should have the same return type and parameter has isalnum.
When passing to remove_if, you're passing the function itself, so you don't need the brackets.
Hmm i am not really sure what that parameter should be. Maybe i need to take a break from this and do i again in a few hours. My brain has stopped working. :D
1
2
3
4
5
6
bool NotAlphaNum (char ch)
{
  return (::isalnum(ch) == 0);
}

tempbook.erase(remove_if(tempbook.begin(), tempbook.end(), NotAlphaNum()), tempbook.end());
You say don't what type of container tempbook is, but based on your other posts, I'm assuming it is a string. It doesn't really matter a whole lot as long as the container supports a forward iterator.

You're trying to combine two functions in a way that won't work.
- string.erase() removes a character pointed to by an iterator.
- remove_if() removes those elements that match the predicate.

The code you have is going to result in undefined behavior. tempbook.erase() expects an iterator pointing to the element to be removed from the container. remove_if() returns a new "past end" iterator as its return value, which is what is passed to tempbook.erase() and that is what tempbook.erase is going to try and remove. So tempbook.erase() is going to try and remove an element past the end of the container (string).

To answer your question, simply supply your own predicate to remove_if that returns true if the character is not alphanumeric.

1
2
3
4
5
bool not_alnum (int c)
{  return ! alnum(c);
}

  remove_if (tempbook.begin(), tempbook.end(), not_alnum);

Last edited on
You're trying to combine two functions in a way that won't work.
- string.erase() removes a character pointed to by an iterator.
- remove_if() removes those elements that match the predicate.

One version of string.erase() removes a character pointed to by an iterator. Not the version used here. And, perhaps somewhat surprisingly, remove_if doesn't remove anything.

http://en.cppreference.com/w/cpp/string/basic_string/erase
(We're using #3.)


The code you have is going to result in undefined behavior.

Nope!

remove_if() returns a new "past end" iterator as its return value,

What remove_if returns is a valid iterator that, if remove_if actually removed anything, would be the iterator returned by tempbook.end(). But, since it doesn't actually remove anything, we need to erase those elements from that iterator to the end of the string in order to finish the job.

https://en.wikipedia.org/wiki/Erase%E2%80%93remove_idiom
Last edited on
Thanks cire
Last edited on
Thanks for the help everyone. I needed a few hours rest in order to understand most of the reply:s. Guess i was a bit tired hehe.

I ended up using cire code that he posted in another forum topic and it worked perfect.

1
2
auto not_alnum = [](char ch) { return !std::isalnum(ch); };
tempbook.erase(remove_if(tempbook.begin(), tempbook.end(), not_alnum), tempbook.end());
Topic archived. No new replies allowed.