Determine if a string contains only alphanumeric characters (or a space)
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
Comments
-
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 almost 14 years+1. Also you can use
isspace()
if you want to count other types of whitespace (e.g. tab). -
TOMKA almost 14 yearsThanks for the advice, what is the benefit of this anonymous namespaces over using static functions?
-
minyatur almost 14 yearsIt's deprecated by current c++ standards for this use.
-
TOMKA almost 14 yearsWow 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 almost 14 years@dreamlax - yes, that's possible. I've updated the answer to do that.
-
TOMKA almost 14 yearsThe syntax is initially confusing, but I'm sure I'll get used to it.
-
johnsyweb almost 14 yearsThe 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 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 thefind_if
is to find the first element that satisfies the predicate, the predicate being "not alphanumeric or space". If we getstr.end()
we know that no character satisfied that predicate, so they must all be alphanumeric or space characters. -
johnsyweb almost 14 years@dreamlax: You are right. It has clearly been a long week :-)
-
5andr0 over 11 years@Johnsyweb If you want it more readable use find_if_not instead ;)
-
rmbianchi over 3 yearsPerfect! Thanks a lot!! +1!
-
Vega4 over 2 yearsJust pass "🔒" to the function on input and it would insta-throw at C++ runtime level (MS Runtime at least).
-
Vega4 over 2 yearsThere 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.