Objective-C преобразовывает шестнадцатеричную строку в целое число

94

Я хотел бы знать, как разобрать шестнадцатеричную строку, представляющую число, в Objective-C. Я готов использовать как объективный, так и метод на основе C.

пример:

#01FFFFAB

следует разобрать на целое число: 33554347

Любая помощь будет оценена по достоинству!

Ричард Дж. Росс III
источник

Ответы:

169

Ответ Джошуа Вайнберга в основном правильный, однако 0xпрефикс не является обязательным при сканировании шестнадцатеричных целых чисел. Если у вас есть строка в формате #01FFFFAB, вы все равно можете использовать NSScanner, но вы можете пропустить первый символ.

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

[scanner setScanLocation:1]; // bypass '#' character
[scanner scanHexInt:&result];
мечта
источник
1
Спасибо, именно то, что мне нужно!
Ричард Дж. Росс III
Обратите внимание: если вы хотите выполнить строгий синтаксический анализ, вы должны сначала убедиться, что строка не начинается с 0x(или 0X). NSScanner примет эти префиксы.
Крис Пейдж
63

вы можете использовать для этого NSScanner

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

outValбудет содержать искомое int. 0x не является обязательным.

Джошуа Вайнберг
источник
1
Кроме того, вы можете использовать подстановку строки для преобразования символа # в префикс 0x.
hotpaw2 06
должно быть без знака int outVal;
wanghq 01
12

strtol () - ваш друг.

Он преобразует строку в длинную, и вы можете передать основание числа. Сначала уберите этот знак # или передайте strtol указатель на первый числовой символ.

Грэм Перкс
источник
1
Я использую этот метод, который проще (и потенциально быстрее), чем размещение nsscanner.
Крис
1
@Chris: Вероятно, это не быстрее, если у вас есть NSString, потому что вам нужно преобразовать NSString в строку C, прежде чем вы сможете использовать strtol. Если у вас уже есть текст в строке C, он, вероятно, будет быстрее, но если вы не сделаете это тысячи или миллионы раз, я сомневаюсь, что вы почувствуете снижение производительности.
dreamlax
4
int res = strtol ([yourString UTF8String], NULL, base)
loretoparisi
1
@dreamlax Определение - [NSString UTF8String] показывает, что он возвращает указатель на поддерживающую строку UTF8 C (NS_RETURNS_INNER_POINTER). На высоком уровне это всего лишь одна операция, чтобы вернуть этот указатель const char по сравнению с накладными расходами на выделение памяти для NSScanner, копируя входной параметр NSString, не говоря уже о дополнительной задержке передачи сообщений ObjC, возникающей при каждом вызове метода ObjC. Алгоритмически намного быстрее использовать strtoull (), но вы, скорее всего, не заметите разницы, если не проводите сравнительный анализ сканирования шестнадцатеричных целых чисел из миллионов строк :-)
Джейкоб
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 Я добавил некоторые пояснения
Александр Васенин
0

Согласно яблоку:

Объект NSScanner интерпретирует и преобразует символы объекта NSString в числовые и строковые значения.

Итак, если у вас есть NSDataцель, вы можете сделать дальше

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
Jnelson
источник