Objective-C hex dizesini tam sayıya ayrıştırır


94

Objective-C'de bir sayıyı temsil eden bir onaltılık dizeyi nasıl ayrıştıracağımı bilmek istiyorum. Hem amaç, hem de C tabanlı bir yöntem kullanmaya istekliyim, ya da sorun değil.

misal:

#01FFFFAB

33554347 tam sayıya ayrıştırılmalıdır

Herhangi bir yardım memnuniyetle karşılanacaktır!

Yanıtlar:


169

Joshua Weinberg'in cevabı çoğunlukla doğrudur, ancak 0xonaltılık tam sayıları tararken önek isteğe bağlıdır. Biçimde bir dizeniz #01FFFFABvarsa, yine de kullanabilirsiniz NSScanner, ancak ilk karakteri atlayabilirsiniz.

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

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

1
Teşekkürler, tam olarak ihtiyacım olan şey!
Richard J. Ross III

Kesin ayrıştırma yapmak istiyorsanız, önce dizenin 0x(veya 0X) ile başlamadığını kontrol etmelisiniz . NSScanner bu önekleri kabul edecektir.
Chris Page

63

bunun için NSScanner'ı kullanabilirsiniz

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

outValaradığınız int'i içerecektir. 0x isteğe bağlıdır.


1
Ek olarak, # karakterini 0x önekine dönüştürmek için bir dize ikamesi kullanabilirsiniz.
hotpaw2

işaretsiz int outVal olmalıdır;
wanghq

12

strtol () senin arkadaşın.

Bir dizgeyi uzun bir dizgeye dönüştürür ve sayının tabanını içeri aktarabilirsiniz. İlk önce o # işareti kaldırın veya bir göstericiyi ilk sayısal karaktere iletin.


1
Bu yöntemi, bir nsscanner tahsis etmekten çok daha basit (ve potansiyel olarak daha hızlı) kullanıyorum.
Chris

1
@Chris: NSString'iniz varsa muhtemelen daha hızlı değildir, çünkü strtol kullanmadan önce NSString'i bir C dizesine dönüştürmeniz gerekir. Zaten bir C dizesinde metin varsa, muhtemelen daha hızlı olacaktır, ancak bunu binlerce veya milyonlarca kez yapmazsanız, performansın vurduğunu hissedeceğinizden şüpheliyim.
dreamlax

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

1
@dreamlax - [NSString UTF8String] 'in tanımı, UTF8 C dizgesine (NS_RETURNS_INNER_POINTER) bir işaretçi döndürdüğünü gösterir. Yüksek düzeyde, NSScanner için bellek ayırma ek yüküne karşılık bu const karakter işaretçisini döndürmek, NSString giriş parametresini kopyalamak, her ObjC yöntemi çağrısında ortaya çıkan ek ObjC ileti geçirme gecikmesinden bahsetmek bile yalnızca tek bir işlemdir. Strtoull () 'u kullanmak algoritmik olarak çok daha hızlıdır, ancak milyonlarca dizeden onaltılık tam sayıları taramayı karşılaştırmadığınız sürece muhtemelen farkı gözlemlemeyeceksiniz :-)
Jacob

1
strtolFonksiyon aynı zamanda çok daha fazla esnektir. NSScannerSize daha fazla kontrol sağlayan bazı şaşırtıcı uç durumlar bulacağınız için kapsamlı birim testleri yazın (boşluklar, onaltılık olmayan karakterler vb. Dahil) .
Quintin Willison

5

Dönüşüm için aşağıdaki satırı kullanabilirsiniz. Yalnızca tek satırlık kod:

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

Mutlu Kodlama !!!


Sıkı ayrıştırma yapmak istiyorsanız, önce dizenin 0x(veya 0X) veya +/- ile veya girdinizde geçerli olmayan diğer karakterlerle başlamadığını kontrol etmelisiniz .
Chris Page

2

Swift 4 standart kitaplığı, tüm tam sayı türlerini ayrıştırmak için yeni başlatıcıyı tanıttı. Radix (yani taban) ile ayrıştırılması dizge alır ve isteğe bağlı tam sayı döndürür:

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

@MZaragoza Bazı açıklamalar ekledim
Alexander Vasenin

0

Elmaya göre:

Bir NSScanner nesnesi, bir NSString nesnesinin karakterlerini yorumlar ve sayı ve dize değerlerine dönüştürür.

Öyleyse, NSDataobjeniz varsa , sonra yapabilirsiniz

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

Sıkı ayrıştırma yapmak istiyorsanız, önce dizenin 0x(veya 0X) ile veya girişinizde geçerli olmayan ancak NSScanner tarafından kabul edilen diğer karakterlerle başlamadığını kontrol etmelisiniz.
Chris Page

0

Swift 3 için:

var hex = "#01FFFFAB"
hex.remove(at: hex.startIndex)
var rgbValue:UInt32 = 0
Scanner(string: hex).scanHexInt32(&rgbValue)
// rgbValue == 33554347
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.