1. ホーム
  2. c#

[解決済み] この文字列の長さは、なぜ文字数より長いのでしょうか?

2022-05-07 21:10:43

質問

このコード

string a = "abc";
string b = "A????C";
Console.WriteLine("Length a = {0}", a.Length);
Console.WriteLine("Length b = {0}", b.Length);

を出力します。

Length a = 3
Length b = 4

なぜ?唯一想像できるのは、漢字が2バイトであることと .Length メソッドはバイト数を返します。

どのように解決するのですか?

誰もが表面的な答えを言っていますが、深い理由もあります。quot;文字数"は定義が難しい問題で、計算には驚くほどコストがかかりますが、長さのプロパティは高速であるべきです。

なぜ定義が難しいのか?それは、いくつかの選択肢があり、どれが一番有効ということがないからです。

  • コードユニット(バイトまたは他の固定サイズのデータチャンク。C#とWindowsは通常UTF-16を使用するので、2バイトの数を返す)の数は、コンピュータが多くの目的でその形式でデータを処理する必要があるため、確かに関連しています(例えば、ファイルへの書き込みは文字ではなくバイトを気にします)。

  • Unicode コードポイントの数はかなり簡単に計算でき(文字列をスキャンしてサロゲートペアを探す必要があるので O(n) ですが)、テキストエディタにとっては重要かもしれませんが、実は画面に印刷される文字の数(グラフェムといいます)とは同じものではありません。例えば、アクセントのある文字は、1つのコードポイントか、2つのポイントが対になっており、1つはその文字を表し、もう1つは "私のパートナーの文字にアクセントを加えてください"というものです。このペアは2文字でしょうか、それとも1文字でしょうか?文字列を正規化することでこの問題を解決できますが、すべての有効な文字が単一のコードポイント表現を持つわけではありません。

  • また、文字によっては多くのフォントで重なり合って印刷されるため(カーニング)、画面上の文字列の長さは必ずしも字母の長さの合計と同じではありません。

  • Unicodeポイントの中には、伝統的な意味での文字ではなく、ある種の制御マーカーであるものもあります。バイトオーダーマーカーや右から左へのインジケーターのようなものです。これらはカウントされるのでしょうか?

要するに、文字列の長さは実はとんでもなく複雑な問題で、計算するにはデータテーブルだけでなく、CPUの時間もかなりかかるのです。

さらに、何が言いたいのか?なぜこれらの測定基準が重要なのか?それは、あなたのケースで答えられるのはあなただけですが、個人的には、一般的には関係ないと思っています。データ入力の制限は、転送または保存する必要があるものなので、バイト制限によってより論理的に行われると私は考えています。表示サイズの制限は、表示側のソフトウェアで行うのがよいでしょう。メッセージのピクセル数が100であれば、何文字入るかはフォントなどに依存し、データレイヤーのソフトウェアではわからないのです。最後に、unicode標準の複雑さを考えると、他の方法を試すと、エッジケースでバグが発生する可能性があります。

ですから、あまり汎用的な使い方はできない難しい問題です。コードユニット数は計算が簡単で、基礎となるデータ配列の長さであり、一般的なルールとして最も意味があり有用で、定義も単純である。

そのため b は長さがあります 4 ドキュメントにそう書いてあるから」という表面的な説明を超えて。