Objective-C analysiert Hex-Zeichenfolge in Ganzzahl

94

Ich möchte wissen, wie man eine Hex-Zeichenfolge, die eine Zahl darstellt, in Objective-C analysiert. Ich bin bereit, sowohl eine objektive als auch eine C-basierte Methode zu verwenden.

Beispiel:

#01FFFFAB

sollte in die ganze Zahl analysieren: 33554347

Jede Hilfe wäre dankbar!

Richard J. Ross III
quelle

Antworten:

169

Die Antwort von Joshua Weinberg ist größtenteils richtig, das 0xPräfix ist jedoch optional, wenn hexadezimale Ganzzahlen gescannt werden. Wenn Sie eine Zeichenfolge im Format haben #01FFFFAB, können Sie diese weiterhin verwenden NSScanner, aber das erste Zeichen überspringen.

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

[scanner setScanLocation:1]; // bypass '#' character
[scanner scanHexInt:&result];
Dreamlax
quelle
1
Danke, genau das, was ich brauchte!
Richard J. Ross III
Beachten Sie, dass Sie, wenn Sie eine strikte Analyse durchführen möchten, zunächst überprüfen sollten, ob die Zeichenfolge nicht mit 0x(oder 0X) beginnt . NSScanner akzeptiert diese Präfixe.
Chris Seite
63

Sie verwenden können NSScanner für diese

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

outValenthält das int, das Sie suchen. Das 0x ist optional.

Joshua Weinberg
quelle
1
Darüber hinaus können Sie eine Zeichenfolgenersetzung verwenden, um das Zeichen # in das Präfix 0x zu konvertieren.
hotpaw2
sollte unsigniert sein int outVal;
Wanghq
12

strtol () ist dein Freund.

Es konvertiert eine Zeichenfolge in eine lange, und Sie können die Basis der Zahl in übergeben. Entfernen Sie das # -Zeichen jedoch zuerst oder übergeben Sie einen Zeiger auf das erste numerische Zeichen.

Graham Perks
quelle
1
Ich gehe mit dieser Methode viel einfacher (und möglicherweise schneller) als die Zuweisung eines Nsscanners.
Chris
1
@ Chris: Es ist wahrscheinlich nicht schneller, wenn Sie einen NSString haben, da Sie den NSString in einen C-String konvertieren müssen, bevor Sie strtol verwenden können. Wenn Sie den Text bereits in einer C-Zeichenfolge haben, wird er wahrscheinlich schneller sein, aber wenn Sie dies nicht tausend- oder millionenfach tun, bezweifle ich, dass Sie die Leistung beeinträchtigen würden.
Dreamlax
4
int res = strtol ([yourString UTF8String], NULL, Basis)
loretoparisi
1
@dreamlax Die Definition von - [NSString UTF8String] zeigt, dass ein Zeiger auf die unterstützende UTF8 C-Zeichenfolge (NS_RETURNS_INNER_POINTER) zurückgegeben wird. Auf hoher Ebene ist es nur eine einzige Operation, diesen const char-Zeiger gegenüber dem Overhead des Zuweisens von Speicher für NSScanner zurückzugeben, indem der NSString-Eingabeparameter kopiert wird, ganz zu schweigen von der zusätzlichen Latenz beim Übergeben von ObjC-Nachrichten, die bei jedem Aufruf der ObjC-Methode auftritt. Es ist algorithmisch viel schneller, strtoull () zu verwenden, aber Sie werden den Unterschied wahrscheinlich nicht bemerken, wenn Sie nicht das Scannen von Hex-Ganzzahlen aus Millionen von Zeichenfolgen vergleichen :-)
Jacob
1
Die strtolFunktion ist auch viel milder. Schreiben Sie gründliche Komponententests (einschließlich Leerzeichen, nicht hexadezimale Zeichen usw.), da Sie einige überraschende Randfälle finden, über NSScannerdie Sie mehr Kontrolle haben.
Quintin Willison
5

Sie können die folgende Zeile für die Konvertierung verwenden. Es ist nur ein Zeilencode:

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

Viel Spaß beim Codieren !!!

Sahil Mahajan
quelle
Beachten Sie, dass Sie, wenn Sie eine strikte Analyse durchführen möchten, zunächst überprüfen sollten, ob die Zeichenfolge nicht mit 0x(oder 0X) oder +/- oder anderen Zeichen beginnt , die in Ihrer Eingabe nicht als gültig angesehen werden.
Chris Seite
2

In der Swift 4- Standardbibliothek wurde ein neuer Initialisierer zum Parsen aller Ganzzahltypen eingeführt. Zum Parsen mit radix (dh base) ist ein String erforderlich, und es wird eine optionale Ganzzahl zurückgegeben:

let number = Int("01FFFFAB", radix: 16)!
Alexander Vasenin
quelle
@MZaragoza Ich habe einige Erklärungen hinzugefügt
Alexander Vasenin
0

Laut Apfel:

Ein NSScanner-Objekt interpretiert und konvertiert die Zeichen eines NSString-Objekts in Zahlen- und Zeichenfolgenwerte.

NSDataAlso , wenn du ein Objekt hast, kannst du es als nächstes tun

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
quelle
Beachten Sie, dass Sie, wenn Sie eine strikte Analyse durchführen möchten, zunächst überprüfen sollten, ob die Zeichenfolge nicht mit 0x(oder 0X) oder anderen Zeichen beginnt , die in Ihrer Eingabe nicht als gültig angesehen werden, aber von NSScanner akzeptiert werden.
Chris Seite
0

Für Swift 3:

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