problems with find_if function and an overloaded operator

Hi, I'm having some problems understanding what I need to do for the function find_if(). I was reading the article on this website and it looks like this is the way I should be calling the unary function, but the compiler is telling me this isn't so. I'm supposed to have the program run through and clean the words of any punctuation at the beginning of the string and then run through the string and look for punctuation. If there is punctuation in the middle, I'm supposed to "clean" everything after that. So I've run this

1
2
3
4
5
6
7
8
9
10
11
12
13
14
  void clean_entry( const string& s1, string& s2 )
{
size_t start=0, finish=0;

start = find_if (s1.begin(), s1.end(), isalnum); //finds position to start
finish = find_if(s1.begin(), s1.end(),!(isalnum)); //finds position to end

s2 = s1.substr (start, finish); // purges the string of everything after 
                                //punctuation

for_each (s2.begin(), s2.end(), lower); //converts all letters to lowercase

}


and am getting the following errors:
prog4.cc: In function ‘void clean_entry(const string&, std::string&)’:
prog4.cc:59:47: error: no matching function for call to ‘find_if(std::basic_string<char>::const_iterator, std::basic_string<char>::const_iterator, <unresolved overloaded function type>)’
prog4.cc:59:47: note: candidate is:
/usr/include/c++/4.6/bits/stl_algo.h:4418:5: note: template<class _IIter, class _Predicate> _IIter std::find_if(_IIter, _IIter, _Predicate)
prog4.cc:60:48: error: cannot resolve overloaded function ‘isalnum’ based on conversion to type ‘bool’
prog4.cc:60:48: error: in argument to unary !

any help guys?
Last edited on
closed account (o3hC5Di1)
Hi there,

Welcome to the forums.

From the reference on this site: http://www.cplusplus.com/reference/algorithm/find_if/

Returns an iterator to the first element in the range [first,last) for which pred returns true. If no such element is found, the function returns last


isalnum() does not return true or false, it returns an int.

Your best bet is to wrap it in a lambda function:

1
2
3
#include <functional>

start = find_if (s1.begin(), s1.end(), [] (char c) -> bool { return (isalnum(c) > 0); });


Hope that helps.

All the best,
NwN
Thank you for replying (everyone seems so friendly here). I tried that, but I got errors saying that it couldn't convert chars to ints. I'm very confused. If it's iterating through each of the elements, are the elements not passed to the function isalnum? The elements are ints, so would find_if be returning an int?
Can you post the new code and the exact error message you're getting?
Absolutely!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void clean_entry( const string& s1, string& s2 )
{
size_t start=0, finish=0;

start = find_if (s1.begin(), s1.end(),
[] (char c) -> bool { return (isalnum(c) > 0); }); //finds position to start

finish = find_if(s1.begin(), s1.end(),
[] (char c) -> bool { return (!isalnum(c) > 0); }); //finds position to end

s2 = s1.substr (start, finish); // purges the string of everything after punctu$

for_each (s2.begin(), s2.end(), lower); //converts all letters to lowercase

}


And here is the output:

prog4.cc: In function ‘void clean_entry(const string&, std::string&)’:
prog4.cc:60:49: error: cannot convert ‘__gnu_cxx::__normal_iterator<const char*, std::basic_string<char> >’ to ‘size_t {aka long unsigned int}’ in assignment
prog4.cc:63:50: error: cannot convert ‘__gnu_cxx::__normal_iterator<const char*, std::basic_string<char> >’ to ‘size_t {aka long unsigned int}’ in assignment


closed account (o3hC5Di1)
Hi there,

Another observation:

1
2
3
size_t start=0, finish=0;

start = find_if (s1.begin(), s1.end(), isalnum);


You define start as size_t, essentially a number. However, find_if returns an iterator to the first element matching your predicate function.

1
2
3
4
#include <iterator>

std::iterator<std::string> start;
start = find_if (s1.begin(), s1.end(), isalnum);



Also, you're iterating over a string, so every "element" is going to be a char in the string. not an int.

Hope that helps.

All the best,
NwN
Ok, that makes sense. I went back to the drawing board, drew up an iterator, got a ton of errors, realized that I probably should switch to a const iterator since I'm pulling values from a const string. Still got this one error here.

Here's my code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
void clean_entry( const string& s1, string& s2 )
{
string::const_iterator start;
string::const_iterator finish;

start = find_if (s1.begin(), s1.end(),
[] (char c) -> bool { return (isalnum(c) > 0); }); //finds position to start

finish = find_if(s1.begin(), s1.end(),
[] (char c) -> bool { return (!isalnum(c) > 0); }); //finds position to end

s2 = s1.substr (start, finish); // purges the string of everything after punctuation

for_each (s2.begin(), s2.end(), lower); //converts all letters to lowercase

}



prog4.cc: In function ‘void clean_entry(const string&, std::string&)’:
prog4.cc:66:30: error: no matching function for call to ‘std::basic_string<char>::substr(std::basic_string<char>::const_iterator&, std::basic_string<char>::const_iterator&) const’
prog4.cc:66:30: note: candidate is:
/usr/include/c++/4.6/bits/basic_string.h:2155:7: note: std::basic_string<_CharT, _Traits, _Alloc> std::basic_string<_CharT, _Traits, _Alloc>::substr(std::basic_string<_CharT, _Traits, _Alloc>::size_type, std::basic_string<_CharT, _Traits, _Alloc>::size_type) const [with _CharT = char, _Traits = std::char_traits<char>, _Alloc = std::allocator<char>, std::basic_string<_CharT, _Traits, _Alloc> = std::basic_string<char>, std::basic_string<_CharT, _Traits, _Alloc>::size_type = long unsigned int]
/usr/include/c++/4.6/bits/basic_string.h:2155:7: note:   no known conversion for argument 1 from ‘std::basic_string<char>::const_iterator {aka __gnu_cxx::__normal_iterator<const char*, std::basic_string<char> >}’ to ‘long unsigned int’



Thank you again for your help guys. It's really appreciated.

EDIT: Nevermind, that's in regard to a different problem brought about by the changes that have been implemented. I think I'll take it from here. Thanks a ton guys.
Last edited on
Topic archived. No new replies allowed.