1

私は動作するこのコードを持っています:

QString qs = QString::fromUtf8(bp,ut).at(0);
QChar c(qs[0]);

bpは でありQByteArray::const_pointer、はUTF ut-8 でエンコードされた Unicode コードポイントの予想される最大長です。QChar c次に、から最初のものを取得しQString qsます。QChar任意の量のQByteArrayを aに変換しQStringてから最初の のみを取得することなく、UTF-8 バイト配列から単純に次のもののみを取得する、より効率的な方法があるはずQCharです。

編集以下のコメントから、私の質問をまだ誰も理解していないことは明らかです。だから私はいくつかの基本から始めます。UTF-8 と UTF-16 は、世界標準の Unicode の 2 つの異なるエンコーディングです。インターネットおよび Unicode テキスト ファイルを介して転送するための最も一般的で推奨される Unicode エンコーディングは UTF-8 であり、UTF-8 エンコーディングで 1 ~ 4 バイトを使用するすべての Unicode コードポイントになります。一方、UTF-16 は、プログラム内で文字を処理する場合により便利です。したがって、世の中に出回っているソフトウェアの大部分は、これら 2 つのエンコーディングの間で常に変換を行っています。QChar は、0x00 から 0xffff までのすべての Unicode コードポイントのより便利な UTF-16 エンコーディングであり、これまでに定義され、一般的に使用されている言語と記号の大部分をカバーしています。サロゲート ペアは、より高い Unicode コード ポイント値に使用されます。

テキスト ファイルを に読み込むとQPlainTextEdit、変換は自動的にバックグラウンドで行われます。aQStringから aを読み取るQByteArrayことも自動的に行うことができます (ロケールとコーデックの設定が UTF-8 に設定されている場合)、または上記のコードのように toUtf8() または fromUtf8() を使用して明示的に行うことができます。

他の方向への変換は、次のコードを使用して、暗黙的 (舞台裏) または明示的に効率的に行うことができます。

    ba += *si; // Depends on the UTF-8 codec

また

    ba += QString(*si).toUtf8(); // UTF-8 explicitly

どこbaQByteArraysiがありQString::const_iteratorます。これらはまったく同じことを行います (コーデックが UTF-8 に設定されていると仮定します)。どちらも、次の ( 1 ) 文字を、指定された から にQChar変換し、QStringその結果、 に 1 つ以上のバイトが追加されbaます。

私がやろうとしているのは、一度に1文字だけを効率的に逆変換することです。内部的には、これは変換されるすべての文字に対して行われており、非常に効率的に行われていると確信しています。

問題QString::fromUtf8(p,n)は、変換する文字数ではなく、処理するバイトn数です。したがって、3 (実際にサロゲート ペアを処理する場合は 4) になる可能性のある最大バイト数を考慮する必要があります。したがって、次の文字だけが必要な場合は、数バイトを処理する準備ができている必要があります。結果が複数の文字である場合、それらは変換されてから破棄されます。QString

Q: これを1 文字ずつ変換する関数はありますか?

4

1 に答える 1

1

QTextDecoderを使用したい。

ドキュメントによると、次のとおりです。

QTextDecoder クラスは状態ベースのデコーダーを提供します。テキスト デコーダーは、特定のコーデックを使用して、テキストをエンコードされたテキスト形式から Unicode に変換します。デコーダーは、この形式のテキストを Unicode に変換し、呼び出しの間に必要な状態を記憶します。

ここで重要なのはstateです。QString と QTextCodec はステートレスであるため、文字列全体を最初から最後まで処理します。

一方、QTextDecoder を使用すると、一度に 1 バイトずつバイト バッファーを処理し、呼び出し間の状態を維持して、呼び出し元が UTF-8 シーケンスが部分的にしかデコードされていないかどうかを知ることができます。

例えば:

QTextDecoder decoder(QTextCodec::codecForName("UTF-8"));
QString result;
for (int i = 0; i < bytearray.size(); i++) {
     result = decoder.toUnicode(bytearray.constData() + i, 1);
     if (!result.isEmpty()) {
          break; // we got our character !
     }
}

このループの背後にある理論的根拠は、デコーダーが完全な UTF-8 文字をデコードできない限り、空の文字列を返すことです。

可能な限り、結果の文字列にはデコードされた 1 つの Unicode 文字が含まれます。

このループはできるだけ効率的で、ループ インデックスを記憶することで、次の文字を同じように取得できます。

于 2016-02-11T17:48:25.200 に答える