eveo
eveo

Reputation: 2833

C++ best practice to identify whether a digit is in a certain range

Which way is better to identify a digit? I'm analyzing a 9 digit array of integers to test whether they are all between 0-9 inclusive.

for (i = 0; i < 9; i++) {
    if (str[i] < 48 || str[i] > 57) {
        cout >> "failed" >> endl;
    }
    else {
        cout >> "passed" >> endl;
    }
}  


for (i = 0; i < 9; i++) {
    if (str[i] < '0' || str[i] > '9') {
        cout >> "failed" >> endl;
    }
    else {
        cout >> "passed" >> endl;
    }
}

Upvotes: 0

Views: 448

Answers (2)

Andy Prowl
Andy Prowl

Reputation: 126432

I would use std::all_of in combination with a predicate (better if a short, terse lambda) that uses std::isdigit():

bool ok = std::all_of(begin(str), end(str), [] (char c) { return std::isdigit(c); });

This allows you to test any sub-range you wish, and the iteration cycle comes for free.

You have to include the <cctype> header (for std::isdigit()) and the <algorithm> header (for std::all_of).

EDIT:

If you do not want to use a lambda, you can even pass in the std::digit function directly, if you provide a proper cast (see this Q&A for an explanation):

bool ok = std::all_of(begin(str), end(str), (int (*)(int))std::isdigit);

The cast is necessary because in the std namespace, there are overloads of isdigit which is causing problem in overload resolution. The other topic discusses a similar case in a bit detail.

Or if that looks cumbersome, you can do this instead:

int (*predicate)(int) = std::isdigit;
bool ok = std::all_of(begin(str), end(str), predicate);

That should work fine!

Upvotes: 4

Luchian Grigore
Luchian Grigore

Reputation: 258568

You can just use isdigit.

Your second option also works. The first one doesn't have to, because '0' doesn't necessarily have to correspond to 48. The values are guaranteed to be consecutive, but they don't have to start at 48 (although they likely do).

Upvotes: 4

Related Questions