有没有办法在Delphi 2009中查看字符是否使用1或2个字节?

时间:2008-10-10 09:07:04

标签: delphi unicode delphi-2009 character-encoding

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

我感兴趣的是,是否有人知道在逐个字符的基础上可以找出它是否适合单个字节的方式,例如找出char是ascii还是Unicode。

我最感兴趣的是,在我的字符串进入数据库(oracle,Documentum)之前,字符串将耗尽多少字节。

我们需要能够事先强制执行限制(因为我们拥有大量的安装基础),而无需更改数据库。如果字符串字段允许12个字节,则在delphi 2009中,长度为7的字符串将始终显示为使用14个字节,即使它到达数据库时,如果是ascii则仅使用7或如果是双字节则使用14,或者如果是混合物

7 个答案:

答案 0 :(得分:5)

您可以检查角色的值:

if ord(c) < 128 then
    // is an ascii character

答案 1 :(得分:4)

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

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

假设数据库使用Unicode字符集,最可能的编码是UTF-8。这是一个可变长度编码:字符可能需要1到4个字节之间的任何位置,具体取决于字符。您可以在维基百科上看到有关范围如何映射的图表。

但是,如果您根本没有更改数据库架构,那么这必须意味着以下三点之一:

  1. 您目前以二进制方式存储所有内容,而不是文本方式(通常不是一个好的选择)
  2. 数据库已经存储了Unicode并计算了字符数,而不是字节数(否则,你现在遇到了问题,在重音字母的情况下更是如此)
  3. 数据库存储在单字节代码页(例如Windows-1252)中,阻止您完全存储Unicode数据(使其成为非问题,因为字符将以与以前相同的方式存储,尽管您可以' t使用Unicode)
  4. 我不熟悉Oracle,但是如果你看一下MSSQL,它们有两种不同的数据类型:varchar和nvarchar。 Varchar以字节为单位,而nvarchar以字符计数,因此适用于Unicode。另一方面,MySQL只有varchar,它总是以字符计数(从4.1开始)。因此,您应该检查Oracle文档和数据库架构,以获得关于它是否是一个问题的决定性答案。

答案 2 :(得分: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;

答案 3 :(得分:2)

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

答案 4 :(得分:1)

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

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

答案 5 :(得分:0)

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

答案 6 :(得分:-1)

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