What am I iterating in this find_if function?

Here is my code:

bool isNotValid (char a) {
    if (isalpha(a) || a == '_')
    {
        cout << "\n- isalpha";
        return 0;
    }
    else
    {
        cout << "\n- notalpha";
        return 1;
    }
}

bool test123(const string& test)
{
    return find_if(test.begin(), test.end(), isNotValid) != test.end();
}

int main()
{
    string test;
    cout << "Test input: ";
    cin >> test;
    
    if (!test123(test))
        cout << "\n- Valid\n";
    else
        cout << "\n- Not Valid\n";
    return 0;
}

This is part of my code to check the validity of username in my program. I don’t really understand what exactly I am iterating through when I insert the string into my function as address of the string. CPP reference states that find_if iterates from first to last position of a sequence.

Poked through the code with cout at different location, still didn’t quite catch what is going on.

>Solution :

You are iterating your string. You did not pass the address of the string. The function takes the string as a reference to const, meaning it passes the actual string (no copy is made) and the function is not allowed to modify the string. You are iterating character by character in your string and calling your function isNotValid() on each character.

Notes:

  • Instead of returning 1 or 0 from isNotValid(), return true or false.
  • Consider flipping your logic and renaming the function to isValid() instead. You would also have to change test123() to use std::find_if_not().

Here’s my take on your code:

#include <algorithm>
#include <cctype>
#include <iostream>
#include <string>

bool isValid(char a) {
  return std::isalpha(static_cast<unsigned char>(a)) || a == '_';  // !
}

bool test123(const std::string& test) {
  return std::find_if_not(test.begin(), test.end(), isValid) == test.end();  // !
}

int main() {
  std::string testOne{"i_am_valid"};
  std::string testTwo{"i_am_invalid_123"};

  std::cout << "Testing: " << testOne << " : " << std::boolalpha
            << test123(testOne) << '\n';
  std::cout << "Testing: " << testTwo << " : " << std::boolalpha
            << test123(testTwo) << '\n';
}

Output:

❯ ./a.out 
Testing: i_am_valid : true
Testing: i_am_invalid_123 : false

Leave a Reply