アプリケーションを作成し、C++
これを知る必要があります。
テキストのエンコードはUTF8
、バイトから文字への単射写像ですか?つまり、すべての文字 (文字...) は一方向でのみエンコードされますか? したがって、たとえば文字「Ž」は、たとえば 3231 と 32119 の両方としてエンコードすることはできません。
アプリケーションを作成し、C++
これを知る必要があります。
テキストのエンコードはUTF8
、バイトから文字への単射写像ですか?つまり、すべての文字 (文字...) は一方向でのみエンコードされますか? したがって、たとえば文字「Ž」は、たとえば 3231 と 32119 の両方としてエンコードすることはできません。
それは、あなたが「手紙」と考えるものに大きく依存します。
UTF8 は基本的に Unicode のごく一部です。
基本的に、少なくとも 3 つのレベルがあります。バイト、コード ポイント、書記素クラスタです。コード ポイントは、UTF8、UTF16、UTF32 などの特定のエンコーディングに従って、1 バイト以上でエンコードできます。このエンコーディングは一意です (すべての代替方法が無効であると宣言されているため)。ただし、いわゆる結合文字があるため、コード ポイントは常にグリフであるとは限りません。このような結合文字は、基本文字に続き、その名前が示すように、基本文字と結合されます。たとえば、結合文字 U+0308 COMBINING DIAERESIS は、前の文字の上に分音符号 (¨) を置きます。したがって、たとえば a (U+0061 LATIN SMALL LETTER A) の後に続く場合、結果は ä になります。ただし、文字 ä (U+00E4 LATIN SMALL LETTER A WITH DIAERESIS) の単一のコード ポイントもあります。
したがって、各コード ポイントには 1 つの有効な UTF 8 エンコーディングがあります (たとえば、U+0061 は「\141」、U+0308 は「\314\210」、U+00e4 は「\303\244」ですが、文字 ä はコード ポイント シーケンス U+0061 U+0308、つまり UTF8 ではバイト シーケンス "\141\314\210" と単一のコード ポイント U+00E4、つまりバイト シーケンス "\303\244" の両方でエンコードされます。
さらに悪いことに、Unicode メーカーは結合文字が基本文字の前ではなく後に続くと判断したため、次のコード ポイント (結合コード ポイントでない場合は、手紙は終わった)。
有効なUTF-8 は実際に各文字を一意にエンコードします。ただし、一般的なコード化スキームに準拠する、いわゆる長すぎるシーケンスがありますが、文字をエンコードするために使用できるのは最短のシーケンスのみであるため、定義上は無効です。
たとえば、null で終わる文字列と互換性のあるエンコーディングを取得する代わりに、NUL を長すぎるシーケンスとしてエンコードする、変更されたUTF-8 と呼ばれる UTF-8 の派生物があります。0xC0 0x80
0x00
文字ではなく書記素クラスター (つまり、ユーザーが認識する文字) について質問している場合、有効な UTF-8 でさえあいまいです。ただし、Unicode ではいくつかの異なる正規化形式が定義されており、正規化された文字列に制限する場合、UTF-8 は確かに単射です。
やや的外れ: characterのさまざまな概念を視覚化するために思いついた ASCII アートを次に示します。垂直に区切られたのは、人間レベル、抽象レベル、機械レベルです。もっといい名前を考えてください...
[user-perceived characters]<-+
^ |
| |
v |
[characters] <-> [grapheme clusters] |
^ ^ |
| | |
v v |
[bytes] <-> [codepoints] [glyphs]<----------+
話題に戻るには:このグラフは、バイトを使用して抽象文字列を比較するときに発生する可能性のある問題も示しています。特に (UTF-8 を想定)、プログラマーは次のことを確認する必要があります。
はい。UTF-8 は、Unicode 文字をエンコードする標準的な方法です。各 Unicode 文字をエンコードする方法が 1 つだけになるように作成されました。
少し話が逸れます: 一部の文字は見た目が (人間に) 非常に似ていることを知っておくと便利かもしれませんが、それでも違います。たとえば、キリル文字には「/」に非常によく似た記号があります。
はい、そうです。適切に使用する場合、各 Unicode コード ポイントは UTF-8 で一方向にのみエンコードする必要がありますが、これは、任意の文字に適用可能な最短の UTF-8 バイト シーケンスのみを使用する必要があるためです。
ただし、文字をエンコードするために使用される方法は、この要件がなければ、多くの文字を複数の方法でエンコードできます。適切ではありませんが、これが行われる場合もあります。
たとえば、'Z' は0x5a
or {0xa1, 0x9a}
(とりわけ)としてエンコードできます0x5a
が、最短のシーケンスであるため、のみが正しいと見なされます。