Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to check if NSString is contains a numeric value?

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.


Consider NSString integerValue - it returns an NSInteger. However, it will accept some strings that are not entirely numeric and does not provide a mechanism to determine strings which are not numeric at all. This may or may not be acceptable.

For instance, " 13 " -> 13, "42foo" -> 42 and "helloworld" -> 0.

Happy coding.


Now, since the above was sort of a tangent to the question, see determine if string is numeric. Code taken from link, with comments added:

BOOL isNumeric(NSString *s)
{
   NSScanner *sc = [NSScanner scannerWithString: s];
   // We can pass NULL because we don't actually need the value to test
   // for if the string is numeric. This is allowable.
   if ( [sc scanFloat:NULL] )
   {
      // Ensure nothing left in scanner so that "42foo" is not accepted.
      // ("42" would be consumed by scanFloat above leaving "foo".)
      return [sc isAtEnd];
   }
   // Couldn't even scan a float :(
   return NO;
}

The above works with just scanFloat -- e.g. no scanInt -- because the range of a float is much larger than that of an integer (even a 64-bit integer).

This function checks for "totally numeric" and will accept "42" and "0.13E2" but reject " 13 ", "42foo" and "helloworld".


It's very simple.

+ (BOOL)isStringNumeric:(NSString *)text
{
    NSCharacterSet *alphaNums = [NSCharacterSet decimalDigitCharacterSet];
    NSCharacterSet *inStringSet = [NSCharacterSet characterSetWithCharactersInString:text];        
    return [alphaNums isSupersetOfSet:inStringSet];
}

Like this:

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

    NSScanner *ns = [NSScanner scannerWithString:code];
    float the_value;
    if ( [ns scanFloat:&the_value] )
    {
        NSLog(@"INSIDE IF");
        // do something with `the_value` if you like
    }
    else {
    NSLog(@"OUTSIDE IF");
    }
}

Faced same problem in Swift.
In Swift you should use this code, according TomSwift's answer:

func isAllDigits(str: String) -> Bool {

    let nonNumbers = NSCharacterSet.decimalDigitCharacterSet()

    if let range = str.rangeOfCharacterFromSet(nonNumbers) {
        return true
    }
    else {
        return false
    }
}

P.S. Also you can use other NSCharacterSets or their combinations to check your string!