Objective-C将十六进制字符串解析为整数


94

我想知道如何在Objective-C中解析代表数字的十六进制字符串。我愿意同时使用目标或基于C的方法。

例:

#01FFFFAB

应该解析为整数:33554347

任何帮助,将不胜感激!

Answers:


169

Joshua Weinberg的答案基本上是正确的,但是0x在扫描十六进制整数时,前缀是可选的。如果您使用格式的字符串#01FFFFAB,您仍然可以使用 NSScanner,但是您可以跳过第一个字符。

unsigned result = 0;
NSScanner *scanner = [NSScanner scannerWithString:@"#01FFFFAB"];

[scanner setScanLocation:1]; // bypass '#' character
[scanner scanHexInt:&result];

1
谢谢,正是我所需要的!
理查德·罗斯三世

请注意,如果要执行严格的解析,则应首先检查该字符串不是以0x(或0X)开头。NSScanner将接受这些前缀。
克里斯·佩奇

63

您可以为此使用NSScanner

unsigned int outVal;
NSScanner* scanner = [NSScanner scannerWithString:@"0x01FFFFAB"];
[scanner scanHexInt:&outVal];

outVal将包含您要查找的int。0x是可选的。


1
此外,您可以使用字符串替换将#字符转换为0x前缀。
hotpaw2 2010年

应该是无符号的int outVal;
wanghq 2011年

12

strtol()是您的朋友。

它将字符串转换为长整数,您可以传入数字的基数。但是,请先去除#号,否则将其传递给第一个数字字符。


1
我正在使用这种方法,它比分配nsscanner更简单(并且可能更快)。
克里斯(Chris

1
@Chris:如果您有NSString,可能不会更快,因为在使用strtol之前,需要将NSString转换为C字符串。如果您已经在C字符串中添加了文本,它可能会更快,但是除非您执行数千或数百万次,否则我怀疑您会感到性能下降。
dreamlax 2011年

4
int res = strtol([yourString UTF8String],NULL,base)
loretoparisi13年

1
@dreamlax-[NSString UTF8String]的定义表明,它返回指向支持UTF8 C字符串(NS_RETURNS_INNER_POINTER)的指针。在较高的级别上,返回此const char指针与为NSScanner分配内存,复制NSString输入参数的开销只是一个简单的操作,更不用说每次ObjC方法调用都会产生的额外ObjC消息传递延迟。从算法上讲,使用strtoull()的速度要快得多,但是除非您要对数百万个字符串中的扫描十六进制整数进行基准测试,否则您可能不会观察到这种差异:-)
Jacob

1
strtol功能也宽松得多。编写详尽的单元测试(包括空格,非十六进制字符等),因为您会发现一些令人惊讶的边缘情况,这些情况NSScanner使您可以更好地控制。
昆丁·威利森,

5

您可以使用以下行进行转换。它只有一行代码:

NSString *hexString = @"01FFFFAB";
length = (UInt64)strtoull([hexString UTF8String], NULL, 16);
NSLog(@"The required Length is %d", length);

快乐编码!


请注意,如果要执行严格的解析,则应首先检查该字符串不是以0x(或0X)或+/- 开头,或者输入中认为无效的任何其他字符。
克里斯·佩奇

2

Swift 4标准库引入了用于解析所有整数类型的新初始化器。它需要字符串以基数(即基数)进行解析,并返回可选的整数:

let number = Int("01FFFFAB", radix: 16)!

@MZaragoza我添加了一些解释
Alexander Vasenin

0

根据苹果的说法:

NSScanner对象将NSString对象的字符解释并转换为数字和字符串值。

因此,如果您有NSDataobj ,则可以下一步

NSString *dataDescription = data.description;
NSString *dataAsString = [dataDescription substringWithRange:NSMakeRange(1, [dataDescription length]-2)];
unsigned intData = 0;
NSScanner *scanner = [NSScanner scannerWithString:dataAsString];
[scanner scanHexInt:&intData];

请注意,如果要执行严格的解析,则应首先检查该字符串不是以0x(或0X)开头,也不是输入中被认为无效但被NSScanner接受的任何其他字符。
克里斯·佩奇

0

对于Swift 3:

var hex = "#01FFFFAB"
hex.remove(at: hex.startIndex)
var rgbValue:UInt32 = 0
Scanner(string: hex).scanHexInt32(&rgbValue)
// rgbValue == 33554347
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.