Objective-C mem-parsing string hex menjadi integer

94

Saya ingin tahu cara mengurai string hex, mewakili angka, di Objective-C. Saya bersedia menggunakan metode objektif, atau metode berbasis C, baik-baik saja.

contoh:

#01FFFFAB

harus mengurai menjadi integer: 33554347

Bantuan apa pun akan dihargai!

Richard J. Ross III
sumber

Jawaban:

169

Jawaban Joshua Weinberg sebagian besar benar, namun 0xawalannya opsional saat memindai bilangan bulat heksadesimal. Jika Anda memiliki string dalam format #01FFFFAB, Anda masih dapat menggunakan NSScanner, tetapi Anda dapat melewati karakter pertama.

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

[scanner setScanLocation:1]; // bypass '#' character
[scanner scanHexInt:&result];
dreamlax
sumber
1
Terima kasih, apa yang saya butuhkan!
Richard J. Ross III
Perhatikan bahwa jika Anda ingin melakukan penguraian ketat, Anda harus terlebih dahulu memeriksa bahwa string tidak dimulai dengan 0x(atau 0X). NSScanner akan menerima prefiks tersebut.
Chris Page
63

Anda dapat menggunakan NSScanner untuk ini

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

outValakan berisi int yang Anda cari. 0x adalah opsional.

Joshua Weinberg
sumber
1
Selain itu, Anda dapat menggunakan substitusi string untuk mengubah karakter # menjadi awalan 0x.
hotpaw2
harus unsigned int outVal;
wanghq
12

strtol () adalah teman Anda.

Ini mengubah string menjadi panjang, dan Anda dapat meneruskan basis nomor tersebut. Hapus tanda # terlebih dahulu, atau berikan penunjuk ke karakter numerik pertama ke strtol.

Graham Perks
sumber
1
Saya akan menggunakan metode ini, cara yang lebih sederhana (dan berpotensi lebih cepat) daripada mengalokasikan nsscanner.
Chris
1
@ Chris: Mungkin tidak lebih cepat jika Anda memiliki NSString, karena Anda perlu mengonversi NSString ke string C sebelum Anda dapat menggunakan strtol. Jika Anda sudah memiliki teks dalam string C, itu mungkin akan lebih cepat, tetapi kecuali Anda melakukan ini ribuan atau jutaan kali, saya ragu Anda akan merasakan kinerjanya.
dreamlax
4
int res = strtol ([yourString UTF8String], NULL, base)
loretoparisi
1
@dreamlax Definisi - [NSString UTF8String] menunjukkan bahwa ia mengembalikan pointer ke string UTF8 C pendukung (NS_RETURNS_INNER_POINTER). Pada tingkat tinggi, hanya satu operasi untuk mengembalikan pointer char const ini versus overhead alokasi memori untuk NSScanner, menyalin parameter input NSString, belum lagi latensi penyampaian pesan ObjC tambahan yang timbul dengan setiap pemanggilan metode ObjC. Secara algoritme jauh lebih cepat untuk menggunakan strtoull (), tetapi Anda kemungkinan tidak akan mengamati perbedaannya kecuali Anda melakukan benchmarking memindai bilangan bulat hex dari jutaan string :-)
Jacob
1
The strtolfungsi juga lebih banyak ringan. Tulis pengujian unit secara menyeluruh (termasuk spasi, karakter non-hex, dll ..) karena Anda akan menemukan beberapa kasus tepi yang mengejutkan yang NSScannermemberi Anda lebih banyak kendali.
Quintin Willison
5

Anda dapat menggunakan baris di bawah ini untuk konversi. Ini hanya kode satu baris:

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

Selamat Coding !!!

Sahil Mahajan
sumber
Perhatikan bahwa jika Anda ingin melakukan penguraian yang ketat, Anda harus terlebih dahulu memeriksa bahwa string tidak dimulai dengan 0x(atau 0X) atau +/- atau karakter lain yang tidak dianggap valid dalam masukan Anda.
Chris Page
2

Pustaka standar Swift 4 memperkenalkan penginisialisasi baru untuk mengurai semua jenis bilangan bulat. Dibutuhkan string untuk mengurai dengan radix (yaitu base) dan mengembalikan integer opsional:

let number = Int("01FFFFAB", radix: 16)!
Alexander Vasenin
sumber
@MZaragoza Saya menambahkan beberapa penjelasan
Alexander Vasenin
0

Menurut apel:

Objek NSScanner menafsirkan dan mengubah karakter objek NSString menjadi nilai angka dan string.

jadi, jika Anda memiliki NSDatakeberatan, Anda dapat melakukan selanjutnya

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
sumber
Perhatikan bahwa jika Anda ingin melakukan penguraian yang ketat, Anda harus terlebih dahulu memeriksa bahwa string tidak dimulai dengan 0x(atau 0X) atau karakter lain yang tidak dianggap valid dalam masukan Anda, tetapi diterima oleh NSScanner.
Chris Page
0

Untuk Swift 3:

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