Determine if a string contains only alphanumeric characters (or a space)

43,687

Solution 1

Looks good to me, but you can use isalnum(c) instead of isalpha and isdigit.

Solution 2

And looking forward to C++0x, you'll be able to use lambda functions (you can try this out with gcc 4.5 or VS2010):

bool string_is_valid(const std::string &str)
{
    return find_if(str.begin(), str.end(), 
        [](char c) { return !(isalnum(c) || (c == ' ')); }) == str.end();
}

Solution 3

You can also do this with binders so you can drop the helper function. I'd recommend Boost Binders as they are much easier to use then the standard library binders:

bool string_is_valid(const std::string &str)
{
    return find_if(str.begin(), str.end(),
        !boost::bind(isalnum, _1) || boost::bind(std::not_equal_to<char>, _1, ' ')) == str.end();
}

Solution 4

Minor points, but if you want is_not_alnum_space() to be a helper function that is only visible in that particular compilation unit, you should put it in an anonymous namespace instead of making it static:

namespace {
bool is_not_alnum_space(char c)
{
    return !(isalpha(c) || isdigit(c) || (c == ' '));
}
}
...etc
Share:
43,687
TOMKA
Author by

TOMKA

Choo choo!

Updated on June 05, 2020

Comments

  • TOMKA
    TOMKA almost 4 years

    I am writing a function that determines whether a string contains only alphanumeric characters and spaces. I am effectively testing whether it matches the regular expression ^[[:alnum:] ]+$ but without using regular expressions. This is what I have so far:

    #include <algorithm>
    
    static inline bool is_not_alnum_space(char c)
    {
        return !(isalpha(c) || isdigit(c) || (c == ' '));
    }
    
    bool string_is_valid(const std::string &str)
    {
        return find_if(str.begin(), str.end(), is_not_alnum_space) == str.end();
    }
    

    Is there a better solution, or a “more C++” way to do this?

  • Matt Curtis
    Matt Curtis almost 14 years
    +1. Also you can use isspace() if you want to count other types of whitespace (e.g. tab).
  • TOMKA
    TOMKA almost 14 years
    Thanks for the advice, what is the benefit of this anonymous namespaces over using static functions?
  • minyatur
    minyatur almost 14 years
    It's deprecated by current c++ standards for this use.
  • TOMKA
    TOMKA almost 14 years
    Wow that is crazy and cool at the same time. Although, I don't what to check for all types of whitespace, I just want to check for the space character itself. Is that still possible with binder?
  • R Samuel Klatchko
    R Samuel Klatchko almost 14 years
    @dreamlax - yes, that's possible. I've updated the answer to do that.
  • TOMKA
    TOMKA almost 14 years
    The syntax is initially confusing, but I'm sure I'll get used to it.
  • johnsyweb
    johnsyweb almost 14 years
    The only suggestion that I have for improvement is to not have _not_ in function names as it can make for unreadable code. Consider this instead: return find_if(str.begin(), str.end(), is_alnum_space) != str.end();
  • TOMKA
    TOMKA almost 14 years
    @Johnsyweb: That won't work though. That will return true for a string that contains at least one alphanumeric+space character, but I want to ensure that they are all alphanumeric+space characters. The purpose of the find_if is to find the first element that satisfies the predicate, the predicate being "not alphanumeric or space". If we get str.end() we know that no character satisfied that predicate, so they must all be alphanumeric or space characters.
  • johnsyweb
    johnsyweb almost 14 years
    @dreamlax: You are right. It has clearly been a long week :-)
  • 5andr0
    5andr0 over 11 years
    @Johnsyweb If you want it more readable use find_if_not instead ;)
  • rmbianchi
    rmbianchi over 3 years
    Perfect! Thanks a lot!! +1!
  • Vega4
    Vega4 over 2 years
    Just pass "🔒" to the function on input and it would insta-throw at C++ runtime level (MS Runtime at least).
  • Vega4
    Vega4 over 2 years
    There literally seems to be an assert checking for the byte to be above 0... lol? straight within isctype.cpp used by isalnum() and isctype.cpp and debug data for that file are not even available from MS debug servers.