Objective-Cは、16進文字列を整数に解析します


94

Objective-Cで数値を表す16進文字列を解析する方法を教えてください。私は、目的とCベースの方法のどちらを使用してもかまいません。どちらでもかまいません。

例:

#01FFFFAB

次の整数に解析する必要があります:33554347

何か助けていただければ幸いです!

回答:


169

ジョシュアウェインバーグの答えはほぼ正しい0xですが、16進整数をスキャンする場合、プレフィックスはオプションです。形式の文字列がある場合#01FFFFABでも使用 NSScannerできますが、最初の文字をスキップできます。

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

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

1
ありがとう、まさに私が必要としたもの!
Richard

厳密な解析を実行する場合は、最初に文字列が0x(または0X)で始まっていないことを確認する必要があります。NSScannerはそれらの接頭辞を受け入れます。
クリスページ

63

これにはNSScannerを使用できます

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

outValあなたが探しているintが含まれます。0xはオプションです。


1
さらに、文字列置換を使用して#文字を0xプレフィックスに変換できます。
hotpaw2

unsigned int outValである必要があります。
wanghq 2011

12

strtol()はあなたの友達です。

これは文字列をlongに変換し、数値の底を渡すことができます。ただし、最初に#サインオフするか、最初の数値文字へのポインターをstrtolに渡します。


1
私は、nsscannerを割り当てるよりもはるかに簡単(そして場合によってはより高速)にこのメソッドを使用します。
Chris

1
@Chris:strtolを使用する前にNSStringをC文字列に変換する必要があるため、NSStringを使用している場合はおそらくそれほど速くありません。既にC文字列のテキストがある場合は、おそらくより高速になりますが、これを数千回または数百万回実行しない限り、パフォーマンスに影響があるとは思えません。
dreamlax 2011

4
int res = strtol([yourString UTF8String]、NULL、base)
loretoparisi '28 / 11/13

1
@dreamlax-[NSString UTF8String]の定義は、バッキングUTF8 C文字列(NS_RETURNS_INNER_POINTER)へのポインターを返すことを示しています。大まかに言うと、このconst charポインタを返すのは1つの操作だけで、NSScannerにメモリを割り当て、NSString入力パラメータをコピーするオーバーヘッドと、各ObjCメソッドの呼び出しで発生する追加のObjCメッセージパッシングレイテンシは言うまでもありません。strtoull()を使用する方がアルゴリズム的にはるかに高速ですが、何百万もの文字列から16進整数をスキャンするベンチマークを行わない限り、違いを観察できないでしょう:-)
Jacob

1
このstrtol関数はまた、より寛大です。完全な単体テスト(スペース、16進数以外の文字などを含む)を記述しNSScannerます。これにより、より制御しやすい驚くべきエッジケースが見つかります。
Quintin Willison 2017年

5

以下の行を変換に使用できます。そのたった1行のコード:

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

ハッピーコーディング!!!


厳密な解析を実行する場合は、最初に文字列が0x(または0X)または+/-で始まっていないこと、または入力で有効と見なされないその他の文字がないことを確認してください。
Chris Page

2

Swift 4標準ライブラリは、すべての整数型を解析するための新しい初期化子を導入しました。文字列を基数(つまり、基数)で解析し、オプションの整数を返します。

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

@MZaragoza私はいくつかの説明を追加しました
アレクサンダーワセニン2017

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で受け入れられるその他の文字がないことを確認する必要があります。
クリスページ

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.