Objective-C analisa string hexadecimal para inteiro

94

Gostaria de saber como analisar uma string hexadecimal, representando um número, em Objective-C. Estou disposto a usar um método objetivo ou baseado em C, qualquer um está bom.

exemplo:

#01FFFFAB

deve analisar no número inteiro: 33554347

Qualquer ajuda seria apreciada!

Richard J. Ross III
fonte

Respostas:

169

A resposta de Joshua Weinberg está quase correta, no entanto, o 0xprefixo é opcional ao digitalizar inteiros hexadecimais. Se você tiver uma string no formato #01FFFFAB, ainda poderá usar NSScanner, mas poderá pular o primeiro caractere.

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

[scanner setScanLocation:1]; // bypass '#' character
[scanner scanHexInt:&result];
dreamlax
fonte
1
Obrigado, exatamente o que eu precisava!
Richard J. Ross III
Observe que se você deseja realizar uma análise estrita, deve primeiro verificar se a string não começa com 0x(ou 0X). O NSScanner aceitará esses prefixos.
Chris Page
63

você pode usar o NSScanner para isso

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

outValconterá o int que você está procurando. O 0x é opcional.

Joshua Weinberg
fonte
1
Além disso, você pode usar uma substituição de string para converter o caractere # no prefixo 0x.
hotpaw2
deve ser unsigned int outVal;
wanghq 01 de
12

strtol () é seu amigo.

Ele converte uma string em uma longa, e você pode passar a base do número. No entanto, retire esse # sinal ou passe para o strtol um ponteiro para o primeiro caractere numérico.

Graham Perks
fonte
1
Vou com este método, de maneira mais simples (e potencialmente mais rápido) do que alocar um nsscanner.
Chris
1
@Chris: Provavelmente não é mais rápido se você tiver um NSString, porque você precisa converter o NSString em uma string C antes de usar strtol. Se você já tem o texto em uma string C, provavelmente será mais rápido, mas a menos que você esteja fazendo isso milhares ou milhões de vezes, duvido que sentirá o impacto no desempenho.
Dreamlax
4
int res = strtol ([yourString UTF8String], NULL, base)
loretoparisi
1
@dreamlax A definição de - [NSString UTF8String] mostra que ele retorna um ponteiro para a string C UTF8 de apoio (NS_RETURNS_INNER_POINTER). Em um alto nível, é apenas uma única operação para retornar este ponteiro const char versus a sobrecarga de alocar memória para NSScanner, copiando o parâmetro de entrada NSString, sem mencionar a latência de passagem de mensagem ObjC adicional incorrida com cada invocação de método ObjC. É algoritmicamente muito mais rápido usar strtoull (), mas você provavelmente não observará a diferença, a menos que esteja comparando a varredura de inteiros hexadecimais de milhões de strings :-)
Jacob
1
A strtolfunção também é muito mais branda. Escreva testes de unidade completos (incluindo espaços, caracteres não hexadecimais, etc.), pois você encontrará alguns casos extremos surpreendentes que NSScannerlhe darão mais controle sobre eles.
Quintin Willison
5

Você pode usar a linha abaixo para conversão. É apenas um código de linha:

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

Happy Coding !!!

Sahil Mahajan
fonte
Observe que se você deseja realizar uma análise estrita, deve primeiro verificar se a string não começa com 0x(ou 0X) ou +/- ou qualquer outro caractere que não seja considerado válido em sua entrada.
Chris Page
2

A biblioteca padrão do Swift 4 introduziu um novo inicializador para analisar todos os tipos de inteiros. É necessário string para analisar com base (ou seja, base) e retorna um inteiro opcional:

let number = Int("01FFFFAB", radix: 16)!
Alexander Vasenin
fonte
@MZaragoza Eu adicionei algumas explicações
Alexander Vasenin
0

De acordo com a apple:

Um objeto NSScanner interpreta e converte os caracteres de um objeto NSString em números e valores de string.

então, se você tiver NSDataobj, você pode fazer o próximo

NSString *dataDescription = data.description;
NSString *dataAsString = [dataDescription substringWithRange:NSMakeRange(1, [dataDescription length]-2)];
unsigned intData = 0;
NSScanner *scanner = [NSScanner scannerWithString:dataAsString];
[scanner scanHexInt:&intData];
gbk
fonte
Observe que se você deseja realizar uma análise estrita, deve primeiro verificar se a string não começa com 0x(ou 0X) ou quaisquer outros caracteres que não são considerados válidos em sua entrada, mas que são aceitos pelo NSScanner.
Chris Page
0

Para Swift 3:

var hex = "#01FFFFAB"
hex.remove(at: hex.startIndex)
var rgbValue:UInt32 = 0
Scanner(string: hex).scanHexInt32(&rgbValue)
// rgbValue == 33554347
Jnelson
fonte