Objective-C แยกวิเคราะห์สตริงฐานสิบหกเป็นจำนวนเต็ม


94

ฉันต้องการทราบวิธีแยกวิเคราะห์สตริงฐานสิบหกซึ่งเป็นตัวแทนของตัวเลขใน Objective-C ฉันยินดีที่จะใช้ทั้งวัตถุประสงค์หรือวิธีการตาม C ก็ใช้ได้

ตัวอย่าง:

#01FFFFAB

ควรแยกวิเคราะห์เป็นจำนวนเต็ม: 33554347

ความช่วยเหลือใด ๆ ที่จะได้รับการชื่นชม!

คำตอบ:


170

คำตอบของ Joshua Weinberg ส่วนใหญ่ถูกต้องอย่างไรก็ตาม0xคำนำหน้าเป็นทางเลือกเมื่อสแกนเลขฐานสิบหก หากคุณมีสตริงในรูปแบบ#01FFFFABคุณยังสามารถใช้ได้ NSScannerแต่คุณสามารถข้ามอักขระตัวแรกได้

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

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

1
ขอบคุณสิ่งที่ฉันต้องการ!
Richard J.Ross III

โปรดทราบว่าหากคุณต้องการแยกวิเคราะห์อย่างเข้มงวดคุณควรตรวจสอบก่อนว่าสตริงไม่ได้ขึ้นต้นด้วย0x(หรือ0X) NSScanner จะยอมรับคำนำหน้าเหล่านั้น
Chris Page

63

คุณสามารถใช้NSScannerสำหรับสิ่งนี้

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

outValจะมี int ที่คุณกำลังมองหา 0x เป็นทางเลือก


1
นอกจากนี้คุณสามารถใช้การแทนที่สตริงเพื่อแปลงอักขระ # เป็นคำนำหน้า 0x
hotpaw2

ควรจะไม่ได้ลงนาม int outVal;
wanghq

12

strtol () เป็นเพื่อนของคุณ

มันแปลงสตริงเป็นแบบยาวและคุณสามารถส่งฐานของตัวเลขเข้าไปได้โดยให้ขีดเครื่องหมาย # ออกก่อนหรือส่งไปยัง strtol ตัวชี้ไปยังอักขระตัวเลขตัวแรก


1
ฉันจะใช้วิธีนี้วิธีที่ง่ายกว่า (และอาจเร็วกว่า) กว่าการจัดสรร nsscanner
Chris

1
@Chris: คงไม่เร็วไปกว่านี้ถ้าคุณมี NSString เพราะคุณต้องแปลง NSString เป็นสตริง C ก่อนจึงจะสามารถใช้ strtol ได้ หากคุณมีข้อความในสตริง C อยู่แล้วมันอาจจะเร็วกว่า แต่ถ้าคุณไม่ทำแบบนี้หลายพันหรือหลายล้านครั้งฉันสงสัยว่าคุณจะรู้สึกถึงประสิทธิภาพ
dreamlax

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

1
@dreamlax คำจำกัดความของ - [NSString UTF8String] แสดงว่าส่งกลับตัวชี้ไปยังสตริง UTF8 C สำรอง (NS_RETURNS_INNER_POINTER) ในระดับสูงการดำเนินการเพียงครั้งเดียวในการส่งคืนตัวชี้ const นี้เทียบกับค่าใช้จ่ายในการจัดสรรหน่วยความจำสำหรับ NSScanner คัดลอกพารามิเตอร์อินพุต NSString ไม่ต้องพูดถึงเวลาแฝงในการส่งข้อความ ObjC เพิ่มเติมที่เกิดขึ้นกับการเรียกใช้เมธอด ObjC แต่ละรายการ อัลกอริทึมจะเร็วกว่ามากในการใช้ strtoull () แต่คุณอาจจะไม่สังเกตเห็นความแตกต่างเว้นแต่ว่าคุณกำลังเปรียบเทียบการสแกนจำนวนเต็มฐานสิบหกจากสตริงนับล้าน :-)
Jacob

1
strtolฟังก์ชั่นยังเป็นผ่อนปรนมากขึ้น เขียนการทดสอบหน่วยอย่างละเอียด (รวมถึงช่องว่างอักขระที่ไม่ใช่เลขฐานสิบหก ฯลฯ ) เนื่องจากคุณจะพบกรณีขอบที่น่าแปลกใจที่NSScannerช่วยให้คุณควบคุมได้มากขึ้น
Quintin Willison

5

คุณสามารถใช้บรรทัดด้านล่างสำหรับการแปลง รหัสบรรทัดเดียว:

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

Happy Coding !!!


โปรดทราบว่าหากคุณต้องการแยกวิเคราะห์อย่างเข้มงวดคุณควรตรวจสอบก่อนว่าสตริงไม่ได้ขึ้นต้นด้วย0x(หรือ0X) หรือ +/- หรืออักขระอื่น ๆ ที่ถือว่าไม่ถูกต้องในข้อมูลที่คุณป้อน
Chris Page

2

ไลบรารีมาตรฐานSwift 4เปิดตัว initializer ใหม่สำหรับการแยกวิเคราะห์จำนวนเต็มทุกประเภท ต้องใช้สตริงในการแยกวิเคราะห์ด้วย radix (เช่นฐาน) และส่งกลับจำนวนเต็มที่เป็นทางเลือก:

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

@MZaragoza ฉันได้เพิ่มคำอธิบาย
Alexander Vasenin

0

ตามแอปเปิ้ล:

อ็อบเจ็กต์ NSScanner ตีความและแปลงอักขระของอ็อบเจ็กต์ NSString เป็นค่าตัวเลขและสตริง

ดังนั้นถ้าคุณมีNSDataobj คุณสามารถทำต่อไป

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

โปรดทราบว่าหากคุณต้องการแยกวิเคราะห์อย่างเข้มงวดก่อนอื่นคุณควรตรวจสอบว่าสตริงไม่ได้ขึ้นต้นด้วย0x(หรือ0X) หรืออักขระอื่นใดที่ถือว่าไม่ถูกต้องในอินพุตของคุณ แต่ NSScanner ยอมรับ
Chris Page

0

สำหรับ Swift 3:

var hex = "#01FFFFAB"
hex.remove(at: hex.startIndex)
var rgbValue:UInt32 = 0
Scanner(string: hex).scanHexInt32(&rgbValue)
// rgbValue == 33554347
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.