581

How can I convert a NSString containing a number of any primitive data type (e.g. int, float, char, unsigned int, etc.)? The problem is, I don't know which number type the string will contain at runtime.

I have an idea how to do it, but I'm not sure if this works with any type, also unsigned and floating point values:

long long scannedNumber;
NSScanner *scanner = [NSScanner scannerWithString:aString];
[scanner scanLongLong:&scannedNumber]; 
NSNumber *number = [NSNumber numberWithLongLong: scannedNumber];

Thanks for the help.

brynbodayle
  • 6,546
  • 2
  • 33
  • 49
Enyra
  • 17,542
  • 12
  • 35
  • 44

18 Answers18

1267

Use an NSNumberFormatter:

NSNumberFormatter *f = [[NSNumberFormatter alloc] init];
f.numberStyle = NSNumberFormatterDecimalStyle;
NSNumber *myNumber = [f numberFromString:@"42"];

If the string is not a valid number, then myNumber will be nil. If it is a valid number, then you now have all of the NSNumber goodness to figure out what kind of number it actually is.

Dave DeLong
  • 242,470
  • 58
  • 448
  • 498
  • 16
    For people where it doesn't seem to work: Check if it's related to your locale. The NSNumberFormatter (as far as I know) by default uses the US locale, i.e. expects the decimal separator to be the "." character. If you use "," to separate the fraction, you may need to tell the formatter to use your current locale: [f setLocale:[NSLocale currentLocale]]; – pille Sep 28 '12 at 09:50
  • 2
    @pille by default the locale is the `+currentLocale`, but you're correct; one must always consider the locale when dealing with converting stuff to-and-from human-readable form. – Dave DeLong Nov 22 '12 at 05:57
  • Where did you find that it was currentLocale by default? I can confirm that numberFromString is using dot notation even on a French phone where comma is used. I can confirm that by default, when you output a number, it uses the current locale by default – allaire Jul 24 '15 at 03:19
  • But what if the string can contain either int or float? – GeneCode Dec 09 '16 at 07:40
183

You can use -[NSString integerValue], -[NSString floatValue], etc. However, the correct (locale-sensitive, etc.) way to do this is to use -[NSNumberFormatter numberFromString:] which will give you an NSNumber converted from the appropriate locale and given the settings of the NSNumberFormatter (including whether it will allow floating point values).

Dave DeLong
  • 242,470
  • 58
  • 448
  • 498
Barry Wark
  • 107,306
  • 24
  • 181
  • 206
  • 27
    +q Depending on the situation, non-locale-sensitive might actually be the correct way. – Thilo Sep 12 '11 at 06:46
  • 2
    I had to convert `@"2000"` to an `int` and `[@"2000" integerValue]` worked nicely and is a little simpler for my case. – Besi Feb 02 '12 at 15:09
  • 2
    There are also huge performance differences among these methods. – Tom Andersen Jun 21 '13 at 14:56
  • 2
    this does not work with ARC: it won't convert NSInteger to NSNumber. I have to further use `[NSNumber numberWithInteger ...]` – learner Aug 03 '14 at 03:08
  • What @Thilo said. "Correct" and "locale-sensitive" are not synonyms. The correct thing to do actually depends upon how the number got into the string in the first place. If you read it from user input, then local-sensitive is what you want. From any other source (i.e. you put it there programmatically, you're consuming it as part of the response from some external API, etc.) local-sensitive is not appropriate and could even give incorrect results. – aroth Mar 09 '16 at 04:43
147

Objective-C

(Note: this method doesn't play nice with difference locales, but is slightly faster than a NSNumberFormatter)

NSNumber *num1 = @([@"42" intValue]);
NSNumber *num2 = @([@"42.42" floatValue]);

Swift

Simple but dirty way

// Swift 1.2
if let intValue = "42".toInt() {
    let number1 = NSNumber(integer:intValue)
}

// Swift 2.0
let number2 = Int("42")

// Swift 3.0
NSDecimalNumber(string: "42.42") 

// Using NSNumber
let number3 = NSNumber(float:("42.42" as NSString).floatValue)

The extension-way This is better, really, because it'll play nicely with locales and decimals.

extension String {
    
    var numberValue:NSNumber? {
        let formatter = NumberFormatter()
        formatter.numberStyle = .decimal
        return formatter.number(from: self)
    }
}

Now you can simply do:

let someFloat = "42.42".numberValue
let someInt = "42".numberValue
Kevin R
  • 8,230
  • 4
  • 41
  • 46
  • 1
    I prefer this based on profiling when I was parsing a large amount of string values. Using this syntax rather then an NSNumberFormatter led to significant reduction in time spent parsing the string to NSNumber. And yes the NSNumberFormatter was cached and reused. – androider Mar 05 '14 at 12:27
  • 3
    this literal syntax didn't exist when this question was asked. I'd say this is the correct answer nowadays though. – Chris Sep 25 '14 at 22:09
  • 1
    I agree, but do note that some other countries use the `,` and `.` the other way around (eg `42.000,42`. Something `floatValue` probably does not account for? – Kevin R Oct 27 '14 at 12:49
  • 1
    This is the nicest solution on here, however I have just run a test and you will lose unsigned precision so WATCH OUT!!! – Stoff81 Apr 28 '15 at 11:47
  • In my use case, I needed to get an NSNumber dictionary key from an NSString, so `@([@"42" intValue])` worked perfectly. Not worried about Locale. – Chuck Krutsinger Aug 18 '17 at 17:13
87

For strings starting with integers, e.g., @"123", @"456 ft", @"7.89", etc., use -[NSString integerValue].

So, @([@"12.8 lbs" integerValue]) is like doing [NSNumber numberWithInteger:12].

ma11hew28
  • 121,420
  • 116
  • 450
  • 651
51

You can also do this:

NSNumber *number = @([dictionary[@"id"] intValue]]);

Have fun!

MacMark
  • 6,239
  • 2
  • 36
  • 41
26

If you know that you receive integers, you could use:

NSString* val = @"12";
[NSNumber numberWithInt:[val intValue]];
Ad1905
  • 261
  • 3
  • 3
11

Here's a working sample of NSNumberFormatter reading localized number NSString (xCode 3.2.4, osX 10.6), to save others the hours I've just spent messing around. Beware: while it can handle trailing blanks ("8,765.4 " works), this cannot handle leading white space and this cannot handle stray text characters. (Bad input strings: " 8" and "8q" and "8 q".)

NSString *tempStr = @"8,765.4";  
     // localization allows other thousands separators, also.
NSNumberFormatter * myNumFormatter = [[NSNumberFormatter alloc] init];
[myNumFormatter setLocale:[NSLocale currentLocale]]; // happen by default?
[myNumFormatter setFormatterBehavior:NSNumberFormatterBehavior10_4];
     // next line is very important!
[myNumFormatter setNumberStyle:NSNumberFormatterDecimalStyle]; // crucial

NSNumber *tempNum = [myNumFormatter numberFromString:tempStr];
NSLog(@"string '%@' gives NSNumber '%@' with intValue '%i'", 
    tempStr, tempNum, [tempNum intValue]);
[myNumFormatter release];  // good citizen
miker
  • 189
  • 2
  • 7
5

I wanted to convert a string to a double. This above answer didn't quite work for me. But this did: How to do string conversions in Objective-C?

All I pretty much did was:

double myDouble = [myString doubleValue];
Community
  • 1
  • 1
Anthony
  • 879
  • 3
  • 11
  • 17
5

Thanks All! I am combined feedback and finally manage to convert from text input ( string ) to Integer. Plus it could tell me whether the input is integer :)

NSNumberFormatter * f = [[NSNumberFormatter alloc] init];
[f setNumberStyle:NSNumberFormatterDecimalStyle];
NSNumber * myNumber = [f numberFromString:thresholdInput.text];

int minThreshold = [myNumber intValue]; 

NSLog(@"Setting for minThreshold %i", minThreshold);

if ((int)minThreshold < 1 )
{
    NSLog(@"Not a number");
}
else
{
    NSLog(@"Setting for integer minThreshold %i", minThreshold);
}
[f release];
P.J.Radadiya
  • 1,493
  • 1
  • 12
  • 21
DNA App Lab
  • 51
  • 1
  • 2
4

I think NSDecimalNumber will do it:

Example:

NSNumber *theNumber = [NSDecimalNumber decimalNumberWithString:[stringVariable text]]];

NSDecimalNumber is a subclass of NSNumber, so implicit casting allowed.

JeanNicolas
  • 357
  • 3
  • 9
2

What about C's standard atoi?

int num = atoi([scannedNumber cStringUsingEncoding:NSUTF8StringEncoding]);

Do you think there are any caveats?

martin
  • 93,354
  • 25
  • 191
  • 226
2

You can just use [string intValue] or [string floatValue] or [string doubleValue] etc

You can also use NSNumberFormatter class:

hallucinations
  • 3,424
  • 2
  • 16
  • 23
2

you can also do like this code 8.3.3 ios 10.3 support

[NSNumber numberWithInt:[@"put your string here" intValue]]
Parv Bhasker
  • 1,773
  • 1
  • 20
  • 39
1
NSDecimalNumber *myNumber = [NSDecimalNumber decimalNumberWithString:@"123.45"];
NSLog(@"My Number : %@",myNumber);
Sandip Patel - SM
  • 3,346
  • 29
  • 27
1

Try this

NSNumber *yourNumber = [NSNumber numberWithLongLong:[yourString longLongValue]];

Note - I have used longLongValue as per my requirement. You can also use integerValue, longValue, or any other format depending upon your requirement.

Maple
  • 741
  • 13
  • 28
Rizwan Ahmed
  • 919
  • 13
  • 19
0

Worked in Swift 3

NSDecimalNumber(string: "Your string") 
user431791
  • 341
  • 2
  • 17
0

I know this is very late but below code is working for me.

Try this code

NSNumber *number = @([dictionary[@"keyValue"] intValue]]);

This may help you. Thanks

Ashu
  • 3,373
  • 38
  • 34
-1
extension String {

    var numberValue:NSNumber? {
        let formatter = NumberFormatter()
        formatter.numberStyle = .decimal
        return formatter.number(from: self)
    }
}

let someFloat = "12.34".numberValue
garg
  • 2,651
  • 1
  • 24
  • 21