2011-12-29 7 views
1

CFStringTokenizerを使用してテキストを単語に分解していますが、CFStringが使用しているエンコーディングとUTF8をブリッジするのは難しいです。非ASCII文字が遭遇した場合はC文字列から読み取るしようとしたときUTF8 C文字列のCFStringTokenizerのトークン範囲

NSString *theString = @"Lorem ipsum dolor sit amet!"; 

const char *theCString = [theString cStringUsingEncoding:NSUTF8StringEncoding]; 

tokenizer = CFStringTokenizerCreate(kCFAllocatorDefault, 
            (__bridge CFStringRef)theString, 
            CFRangeMake(0, [theString length]), 
            kCFStringTokenizerUnitWordBoundary, 
            locale); 

while ((tokenType = CFStringTokenizerAdvanceToNextToken(tokenizer)) != kCFStringTokenizerTokenNone) { 
    tokenRange = CFStringTokenizerGetCurrentTokenRange(tokenizer); 
    memcpy(resultPtr, theCString+tokenRange.location, tokenRange.length); 
} 

残念ながらトークナイザによって報告された範囲が正しくありません。このことを考えてみましょう。どのように私のCの文字列から正しい文字をプルできるようにトークナイザから正しい範囲を取得することができますか?

明確にするために、memcpyのものは上記よりも複雑で、ターゲットデバイスであるiPhoneのパフォーマンスに必要です。だから、私はCFStringサブストリングを作成してそれを変換するようなことさえできません。私はC文字列の範囲を必要とします。さまざまな単語境界ライブラリを再実装せずに、それを行うための方法はありますか? (これは、できるだけ多くあるので、私はただ、残念ながら「」を探してを繰り返し処理することはできません。)

アレック

UTF-16ではなく、UTF-8で

答えて

1

NSStringsとCFStrings契約、それISN本当の問題ではない。

  1. あなたはC文字列のインデックスは、元の文字列のインデックスに対応することを想定している:

    あなたのコードは2つの問題があります。

  2. 文字列全体を一度にコピーしてUTF-8 C文字列に変換しています。

#1は範囲の不一致の原因であり、#2は文字列の長さと内容に応じてメモリ使用量が高くなる可能性があります。 (UTF-8は一部のアルファベットで1文字につき4バイトをとり、C文字列ターミネータに1文字を追加することができます)

これらの問題を1回の変更で解決できます。

出力を保持するNSMutableDataを作成します。トークンごとに、データの長さを範囲のlengthに設定します。次に、文字列に目的のエンコーディングで目的の範囲内のバイトを取得し、データのmutableBytesバッファに格納するように指示します。 NSStringにはa method with a very long selector(簡潔にはgetBytes:::::::)があります。

文字列に相対的な範囲の文字列を排他的に使用するため、インデックス/範囲の不一致がなく、各トークンが正しく出力されます。

実際にC文字列が必要な場合は、データの長さを範囲のlength +1に設定してから、トークンバイトを取得した後に最後のバイトを'\0'に個別の割り当てで設定できます。 (別個の代入がなければ、バイトは前の値を保持することがあります)。

+0

ありがとうございましたピーター、私は今getBytesを使用して、範囲の問題を並べ替えました。私はそれがiPhone上で多くのオーバーヘッドを追加するような方法を避けたかったが、今はこのアルゴリズムでは時間の約60%を費やしており、残りの作業はまったく些細なことではありません。残念ながらgetBytesの「NoCopy」バリアント(私が知っているのですか?)はありませんので、私は最適化に関して道路の終わりに達していると思います。 – Max

+0

@Alec:別の質問それはあなたがUTF-8データを使って何をしようとしているのかを示しています。 –

関連する問題