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!

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];

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.


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.


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 !!!


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)!

@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];

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
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.