Objective-C analizza la stringa esadecimale in numero intero


94

Vorrei sapere come analizzare una stringa esadecimale, che rappresenta un numero, in Objective-C. Sono disposto a utilizzare sia un obiettivo che un metodo basato su C, o va bene.

esempio:

#01FFFFAB

dovrebbe analizzare l'intero: 33554347

Qualsiasi aiuto sarebbe apprezzato!

Risposte:


169

La risposta di Joshua Weinberg è per lo più corretta, tuttavia il 0xprefisso è facoltativo durante la scansione di interi esadecimali. Se hai una stringa nel formato #01FFFFAB, puoi comunque usarla NSScanner, ma puoi saltare il primo carattere.

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

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

1
Grazie, esattamente quello di cui avevo bisogno!
Richard J. Ross III

Nota che se vuoi eseguire un'analisi rigorosa, dovresti prima controllare che la stringa non inizi con 0x(o 0X). NSScanner accetterà questi prefissi.
Chris Page

63

puoi usare NSScanner per questo

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

outValconterrà l'int che stai cercando. Lo 0x è facoltativo.


1
Inoltre, è possibile utilizzare una sostituzione di stringa per convertire il carattere # nel prefisso 0x.
hotpaw2

dovrebbe essere unsigned int outVal;
wanghq

12

strtol () è tuo amico.

Converte una stringa in una long, e puoi passare la base del numero in. Togli prima la sigla # o passa per strtol un puntatore al primo carattere numerico.


1
Vado con questo metodo, molto più semplice (e potenzialmente più veloce) rispetto all'assegnazione di un nsscanner.
Chris

1
@ Chris: Probabilmente non è più veloce se hai un NSString, perché dovresti convertire NSString in una stringa C prima di poter usare strtol. Se hai già il testo in una stringa C, probabilmente sarà più veloce, ma a meno che tu non lo stia facendo migliaia o milioni di volte dubito che sentirai il colpo di prestazioni.
dreamlax

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

1
@dreamlax La definizione di - [NSString UTF8String] mostra che restituisce un puntatore alla stringa C UTF8 di supporto (NS_RETURNS_INNER_POINTER). Ad alto livello, è solo una singola operazione per restituire questo puntatore a const char rispetto al sovraccarico dell'allocazione della memoria per NSScanner, copiando il parametro di input NSString, per non parlare della latenza aggiuntiva di passaggio di messaggi ObjC sostenuta con ogni chiamata del metodo ObjC. È algoritmicamente molto più veloce usare strtoull (), ma probabilmente non osserverai la differenza a meno che tu non stia facendo il benchmarking di interi esadecimali da milioni di stringhe :-)
Jacob

1
La strtolfunzione è anche molto più indulgente. Scrivi test unitari approfonditi (includi spazi, caratteri non esadecimali, ecc.) Poiché troverai alcuni casi limite sorprendenti che NSScannerti danno un maggiore controllo.
Quintin Willison

5

Puoi usare la riga sottostante per la conversione. È solo un codice di riga:

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

Codifica felice !!!


Nota che se vuoi eseguire un'analisi rigorosa, dovresti prima controllare che la stringa non inizi con 0x(o 0X) o +/- o altri caratteri che non sono considerati validi nel tuo input.
Chris Page

2

La libreria standard di Swift 4 ha introdotto un nuovo inizializzatore per l'analisi di tutti i tipi interi. Richiede string per analizzare con radix (cioè base) e restituisce un numero intero opzionale:

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

@MZaragoza ho aggiunto alcune spiegazioni
Alexander Vasenin

0

Secondo Apple:

Un oggetto NSScanner interpreta e converte i caratteri di un oggetto NSString in valori numerici e stringa.

quindi, se hai NSDataobj puoi fare il prossimo

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

Tieni presente che se desideri eseguire un'analisi rigorosa, devi prima controllare che la stringa non inizi con 0x(o 0X) o altri caratteri che non sono considerati validi nel tuo input, ma che sono accettati da NSScanner.
Chris Page

0

Per Swift 3:

var hex = "#01FFFFAB"
hex.remove(at: hex.startIndex)
var rgbValue:UInt32 = 0
Scanner(string: hex).scanHexInt32(&rgbValue)
// rgbValue == 33554347
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.