Objective-C phân tích cú pháp chuỗi hex thành số nguyên


94

Tôi muốn biết cách phân tích cú pháp một chuỗi hex, đại diện cho một số, trong Objective-C. Tôi sẵn sàng sử dụng cả phương pháp mục tiêu hoặc phương pháp dựa trên C đều được.

thí dụ:

#01FFFFAB

nên phân tích cú pháp thành số nguyên: 33554347

Bất kỳ trợ giúp sẽ được đánh giá cao!

Câu trả lời:


169

Câu trả lời của Joshua Weinberg hầu hết đúng, tuy nhiên 0xtiền tố là tùy chọn khi quét các số nguyên thập lục phân. Nếu bạn có một chuỗi ở định dạng #01FFFFAB, bạn vẫn có thể sử dụng NSScanner, nhưng bạn có thể bỏ qua ký tự đầu tiên.

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

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

1
Cảm ơn, chính xác những gì tôi cần!
Richard J. Ross III

Lưu ý rằng nếu bạn muốn thực hiện phân tích cú pháp nghiêm ngặt, trước tiên bạn nên kiểm tra xem chuỗi không bắt đầu bằng 0x(hoặc 0X). NSScanner sẽ chấp nhận các tiền tố đó.
Chris Trang

63

bạn có thể sử dụng NSScanner cho việc này

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

outValsẽ chứa int mà bạn đang tìm kiếm. 0x là tùy chọn.


1
Ngoài ra, bạn có thể sử dụng thay thế chuỗi để chuyển ký tự # thành tiền tố 0x.
hotpaw2

nên không dấu int outVal;
wanghq

12

strtol () là bạn của bạn.

Nó chuyển đổi một chuỗi thành một chuỗi dài và bạn có thể chuyển cơ số của số vào. Tuy nhiên, hãy loại bỏ dấu # đó trước hoặc chuyển sang strtol một con trỏ đến ký tự số đầu tiên.


1
Tôi đang sử dụng phương pháp này, đơn giản hơn (và có khả năng nhanh hơn) so với việc phân bổ một nsscanner.
Chris

1
@Chris: Có lẽ không nhanh hơn nếu bạn có NSString, bởi vì bạn cần chuyển đổi NSString thành chuỗi C trước khi có thể sử dụng strtol. Nếu bạn đã có văn bản trong một chuỗi C, nó có thể sẽ nhanh hơn, nhưng trừ khi bạn đang làm điều này hàng ngàn hoặc hàng triệu lần, tôi nghi ngờ bạn sẽ cảm thấy hiệu suất đạt được.
dreamlax

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

1
@dreamlax Định nghĩa của - [NSString UTF8String] cho thấy rằng nó trả về một con trỏ tới chuỗi UTF8 C hỗ trợ (NS_RETURNS_INNER_POINTER). Ở cấp độ cao, chỉ có một thao tác duy nhất để trả về con trỏ const char này so với chi phí cấp phát bộ nhớ cho NSScanner, sao chép tham số đầu vào NSString, chưa kể đến độ trễ truyền thông báo objC bổ sung phát sinh với mỗi lần gọi phương thức objC. Đó là thuật toán nhanh hơn nhiều để sử dụng strtoull (), nhưng bạn có thể sẽ không quan sát sự khác biệt trừ khi bạn đang benchmarking số nguyên quét hex từ hàng triệu chuỗi :-)
Jacob

1
Các strtolchức năng cũng là một nhân hậu hơn rất nhiều. Viết các bài kiểm tra đơn vị kỹ lưỡng (bao gồm khoảng trắng, ký tự không phải hex, v.v.) vì bạn sẽ tìm thấy một số trường hợp cạnh đáng ngạc nhiên NSScannercho phép bạn kiểm soát nhiều hơn.
Quintin Willison

5

Bạn có thể sử dụng dòng dưới đây để chuyển đổi. Chỉ một mã dòng của nó:

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

Chúc bạn mã hóa vui vẻ !!!


Lưu ý rằng nếu bạn muốn thực hiện phân tích cú pháp chặt chẽ, trước tiên bạn nên kiểm tra xem chuỗi không bắt đầu bằng 0x(hoặc 0X) hoặc +/- hoặc bất kỳ ký tự nào khác không được coi là hợp lệ trong đầu vào của bạn.
Chris Trang

2

Thư viện chuẩn Swift 4 đã giới thiệu bộ khởi tạo mới để phân tích cú pháp tất cả các kiểu số nguyên. Nó cần chuỗi để phân tích cú pháp với cơ số (tức là cơ số) và trả về số nguyên tùy chọn:

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

@MZaragoza Tôi đã thêm một số giải thích
Alexander Vasenin

0

Theo apple:

Đối tượng NSScanner thông dịch và chuyển đổi các ký tự của đối tượng NSString thành các giá trị số và chuỗi.

vì vậy, nếu bạn có NSDataobj bạn có thể làm gì tiếp theo

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

Lưu ý rằng nếu bạn muốn thực hiện phân tích cú pháp chặt chẽ, trước tiên bạn nên kiểm tra xem chuỗi không bắt đầu bằng 0x(hoặc 0X) hoặc bất kỳ ký tự nào khác không được coi là hợp lệ trong đầu vào của bạn, nhưng được NSScanner chấp nhận.
Chris Trang

0

Đối với Swift 3:

var hex = "#01FFFFAB"
hex.remove(at: hex.startIndex)
var rgbValue:UInt32 = 0
Scanner(string: hex).scanHexInt32(&rgbValue)
// rgbValue == 33554347
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.