How to check if NSString is contains a numeric value?

C.Johns picture C.Johns · Jul 10, 2011 · Viewed 29.9k times · Source

I have a string that is being generate from a formula, however I only want to use the string as long as all of its characters are numeric, if not that I want to do something different for instance display an error message.

I have been having a look round but am finding it hard to find anything that works along the lines of what I am wanting to do. I have looked at NSScanner but I am not sure if its checking the whole string and then I am not actually sure how to check if these characters are numeric

- (void)isNumeric:(NSString *)code{

    NSScanner *ns = [NSScanner scannerWithString:code];
    if ( [ns scanFloat:NULL] ) //what can I use instead of NULL?
    {
        NSLog(@"INSIDE IF");
    }
    else {
    NSLog(@"OUTSIDE IF");
    }
}

So after a few more hours searching I have stumbled across an implementation that dose exactly what I am looking for.

so if you are looking to check if their are any alphanumeric characters in your NSString this works here

-(bool) isNumeric:(NSString*) hexText
{

    NSNumberFormatter* numberFormatter = [[[NSNumberFormatter alloc] init] autorelease];

    NSNumber* number = [numberFormatter numberFromString:hexText];

    if (number != nil) {
        NSLog(@"%@ is numeric", hexText);
        //do some stuff here      
        return true;
    }

    NSLog(@"%@ is not numeric", hexText);
    //or do some more stuff here
    return false;
}

hope this helps.

Answer

TomSwift picture TomSwift · Dec 9, 2011

Something like this would work:

@interface NSString (usefull_stuff)
- (BOOL) isAllDigits;
@end

@implementation NSString (usefull_stuff)

- (BOOL) isAllDigits
{
    NSCharacterSet* nonNumbers = [[NSCharacterSet decimalDigitCharacterSet] invertedSet];
    NSRange r = [self rangeOfCharacterFromSet: nonNumbers];
    return r.location == NSNotFound && self.length > 0;
}

@end

then just use it like this:

NSString* hasOtherStuff = @"234 other stuff";
NSString* digitsOnly = @"123345999996665003030303030";

BOOL b1 = [hasOtherStuff isAllDigits];
BOOL b2 = [digitsOnly isAllDigits];

You don't have to wrap the functionality in a private category extension like this, but it sure makes it easy to reuse..

I like this solution better than the others since it wont ever overflow some int/float that is being scanned via NSScanner - the number of digits can be pretty much any length.