4

歴史的な理由から、Cocoa の Unicode 実装は 16 ビットです0xFFFF。「サロゲート ペア」を介して上記の Unicode 文字を処理します。これは、次のコードが機能しないことを意味します。

NSString myString = @"";
uint32_t codepoint = [myString characterAtIndex:0];
printf("%04x\n", codepoint);  // incorrectly prints "d842"

さて、このコードは常に 100% 機能しますが、途方もなく冗長です。

NSString myString = @"";
uint32_t codepoint;
[@"" getBytes:&codepoint maxLength:4 usedLength:nil
    encoding:NSUTF32StringEncoding options:0
    range:NSMakeRange(0,2) remainingRange:nil];
printf("%04x\n", codepoint);  // prints "20d20"

そして、このコードを使用するmbtowcと機能しますが、それでもかなり冗長で、グローバル状態に影響し、スレッドセーフではなく、おそらく自動解放プールがいっぱいになります。

setlocale(LC_CTYPE, "UTF-8");
wchar_t codepoint;
mbtowc(&codepoint, [@"" UTF8String], 16);
printf("%04x\n", codepoint);  // prints "20d20"

NSString から最初 (または N 番目) の Unicode コードポイントを抽出するための単純なCocoa/Foundation イディオムはありますか? できれば、コードポイントを返すだけのワンライナーですか?

このCocoa Unicode サポートの優れた要約(記事の終わり近く) で与えられた答えは、単に「試してはいけません。入力にサロゲート ペアが含まれている場合は、それらを処理する適切な方法がないため、それらを除外するか何かを行う必要があります。ちゃんと。"

4

1 に答える 1

5

単一の Unicode コード ポイントがサロゲート ペアである可能性がありますが、すべての言語文字が単一のコード ポイントであるとは限りません。つまり、すべての言語文字が 1 つまたは 2 つの UTF-16 単位で表されるわけではありません。多くの文字は、一連の Unicode コード ポイントで表されます。

これは、Ascii を扱っていない限り、言語文字をインデックスの Unicode コード ポイントではなく、部分文字列と考える必要があることを意味します。

インデックス 0 の文字の部分文字列を取得するには:

NSRange r = [[myString rangeOfComposedCharacterSequenceAtIndex:0];
[myString substringWithRange:r];

これは、実際に何をしたいのかによって、あなたが望むものかもしれませんし、そうでないかもしれません。たとえば、これにより「文字境界」が得られますが、これらは言語固有のカーソル挿入ポイントに対応しません。

于 2012-10-08T23:11:54.797 に答える