4

Delphi 2009 では、文字列型が 2 バイトを使用して文字を表すように変更されました。これにより、Unicode 文字セットがサポートされるようになりました。sizeof(string) を取得すると、 length(String) * sizeof(char) が取得されます。Sizeof(char) は現在 2 です。

私が興味を持っているのは、文字ごとに1バイトに収まるかどうかを確認できる方法を誰かが知っているかどうかです。たとえば、文字がasciiかUnicodeかを確認します。

私が主に知りたいのは、文字列がデータベース (oracle、Documentum) に送られる前に、文字列が何バイト使用するかということです。

データベースを変更せずに、事前に、そして理想的には (大規模なインストール ベースがあるため) 制限を適用できる必要があります。文字列フィールドが 12 バイトを許可する場合、Delphi 2009 では、長さ 7 の文字列は常に 14 バイトを使用していると表示されますが、データベースに到達すると、ascii の場合は 7、2 バイトの場合は 14、または混合。

4

7 に答える 7

5

文字の値を確認できます:

if ord(c) < 128 then
    // is an ascii character
于 2008-10-10T09:09:51.570 に答える
4

まず第一に、データベースの長さは実際にはバイト単位ではなく文字単位である可能性があることに注意してください。データ型についてはドキュメントを確認する必要があります。質問の目的上、実際には後者であると仮定します。

文字列が使用するバイト数は、格納される文字エンコーディングに完全に依存します。Delphi のデフォルトの文字列型である UTF-16 の場合、サロゲートを除いて、常に 1 文字あたり 2 バイトになります。

ただし、データベースが Unicode 文字セットを使用すると仮定すると、最も可能性の高いエンコーディングは UTF-8 です。これは可変長エンコーディングです。文字に応じて、文字は 1 から 4 バイトの間で必要になる場合があります。ウィキペディアで、範囲がどのようにマッピングされているかを示すグラフを確認できます。

ただし、データベース スキーマをまったく変更しない場合は、次の 3 つのいずれかを意味する必要があります。

  1. 現在、すべてをテキスト形式ではなくバイナリ形式で保存しています (通常は適切な選択ではありません)。
  2. データベースには、バイトではなく、Unicode とカウントされた文字が既に格納されています (そうしないと、問題が発生する可能性があります。アクセント付き文字の場合はなおさらです)。
  3. データベースは Windows-1252 などの 1 バイトのコードページで保存されるため、Unicode データをまったく保存できません (使用することはできませんが、文字は以前と同じ方法で保存されるため、問題はありません)。 Unicode の)

私は Oracle に詳しくありませんが、MSSQL を見ると、varchar と nvarchar という 2 つの異なるデータ型があります。Varchar はバイト単位でカウントされますが、nvarchar は文字単位でカウントされるため、Unicode に適しています。一方、MySQL には varchar しかなく、常に文字数でカウントされます (4.1 以降)。したがって、Oracle のドキュメントとデータベース スキーマを調べて、それが問題であるかどうかについて決定的な答えを得る必要があります。

于 2008-10-10T14:29:48.167 に答える
2

StringElementSize関数を使用して、文字列がUnicodeであるかANSIであるかを確認できます。文字がANSIであるかどうかを確認するには、Character.pasユニットのTCharacter.IsAnsiクラス関数を使用します。

于 2008-12-24T20:08:09.473 に答える
2

Delphi 2009 で Unicode を使用したくない場合は、AnsiString 型を使用できます。しかし、なぜあなたはする必要があります。

面倒ですが、有効なテストは次のようになります。

function IsAnsi(const AString: string): Boolean;
var
  tempansi : AnsiString;
  temp : string;
begin
  tempansi := AnsiString(AString);
  temp := tempansi;
  Result := temp = AString;
end;
于 2008-10-10T09:21:09.457 に答える
1

あなたは、文字列が何バイトを占めるかを本当に知りたいと答えました。

UTF8Stringに変換してみませんか?ANSI文字は1バイトを使用します。UTF-8では、Unicode文字が2バイトを超える場合があることに注意してください。

于 2008-11-07T14:51:49.800 に答える
0

AnsiString では 1 文字 = 1 バイト、Unicode 文字列では 1 文字 = 2 バイトなので、実行する簡単なテストは IsAnsiString:= sizeof(aString)=length(aString); です。

于 2008-10-21T16:24:28.663 に答える
-1

ASCII 文字は常に 1 バイトに収まります。エンコード方法に依存するため、Unicode 文字についても同じことは言えません。それが ASCII または Unicode 文字であるか、それとも文字であるかは、1 バイトからはわかりません。それで、あなたの質問は何ですか?そして、なぜあなたは知る必要があるのですか?私の推測では、あなたがユニコードを誤解したか、私があなたの質問を誤解したのでしょう。

于 2008-10-10T09:10:57.743 に答える