4

Delphi 2009 已将其字符串类型更改为使用 2 个字节来表示一个字符,这允许支持 unicode 字符集。现在当你得到 sizeof(string) 你得到 length(String) * sizeof(char) 。Sizeof(char) 当前为 2。

我感兴趣的是是否有人知道一种方法,它可以逐个字符地找出它是否适合单个字节,例如找出一个char是ascii还是Unicode。

我主要想知道的是,在我的字符串进入数据库(oracle、Documentum)之前,该字符串将使用多少字节。

我们需要能够预先实施限制,理想情况下(因为我们有一个庞大的安装基础),而无需更改数据库。如果字符串字段允许 12 个字节,则在 delphi 2009 中,长度为 7 的字符串将始终显示为使用 14 个字节,即使一旦它到达数据库,它只会使用 7(如果是 ascii)或 14(如果是双字节),或者介于两者之间的某个位置混合物。

4

7 回答 7

5

您可以检查字符的值:

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

首先,请记住,您的数据库长度可能实际上是字符,而不是字节 - 您必须检查数据类型的文档。出于问题的目的,我将假设它确实是后者。

您的字符串将使用的字节数完全取决于将要存储的字符编码。如果它是 UTF-16,Delphi 中的默认字符串类型,那么它总是每个字符 2 个字节,不包括代理。

然而,假设数据库使用 Unicode 字符集,最可能的编码是 UTF-8。这是一种可变长度编码:字符可能需要 1 到 4 个字节,具体取决于字符。您可以在 Wikipedia 上查看范围如何映射的图表。

但是,如果您根本不更改数据库架构,那么这一定意味着以下三件事之一:

  1. 您目前以二进制方式存储所有内容,而不是文本方式(通常不是一个好的选择)
  2. 数据库已经存储了 Unicode 和计数字符,而不是字节(否则,你现在会遇到问题,在重音字母的情况下更是如此)
  3. 数据库存储在单字节代码页中,例如 Windows-1252,从而完全阻止您存储 Unicode 数据(这不是问题,因为字符的存储方式与以前相同,尽管您无法使用Unicode)

我对 Oracle 不熟悉,但如果您查看 MSSQL,它们有两种不同的数据类型:varchar 和 nvarchar。Varchar 以字节计,而 nvarchar 以字符计,因此适用于 Unicode。另一方面,MySQL 只有 varchar,而且它总是以字符计(从 4.1 开始)。因此,您应该检查 Oracle 文档和您的数据库架构,以获得关于这是否是一个问题的决定性答案。

于 2008-10-10T14:29:48.167 回答
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 回答
2

您可以使用StringElementSize函数来确定字符串是 Unicode 还是 ANSI。要检查字符是否为 ANSI,请使用Character.pas 单元中的TCharacter.IsAnsi类函数。

于 2008-12-24T20:08:09.473 回答
1

您回答说您真的想知道您的字符串将占用多少字节。

如何转换为 UTF8String?Ansi 字符将占用 1 个字节。请记住,在 UTF-8 中,Unicode 字符可能占用超过 2 个字节。

于 2008-11-07T14:51:49.800 回答
0

由于 AnsiString 1 char = 1 字节和 Unicode String 1 char = 2 字节,执行的简单测试是 IsAnsiString:= sizeof(aString)=length(aString);

于 2008-10-21T16:24:28.663 回答
-1

一个 ASCII 字符总是适合一个字节。您不能对 unicode 字符说同样的话,因为这取决于它的编码方式。您无法从单个字节中看出它是 ASCII 还是 unicode 字符,或者根本就不是字符。那么你的问题又是什么?为什么你需要知道?我的猜测是你误解了 unicode 或者我误解了你的问题。

于 2008-10-10T09:10:57.743 回答