【问题标题】:Index character instead of byte in the Delphi stringDelphi字符串中的索引字符而不是字节
【发布时间】:2018-10-24 09:18:11
【问题描述】:

我正在阅读关于 Delphi 字符串索引的文档,如下所示:

http://docwiki.embarcadero.com/RADStudio/Tokyo/en/String_Types_(Delphi)

有一句话说:

您可以像索引数组一样索引字符串变量。如果 S 是非 UnicodeString 字符串变量且 i 是整数表达式,则 S[i] 表示 S 中的第 i 个字节,对于多字节字符串 (MBCS),它可能根本不是第 i 个字符或整个字符。同样,索引 UnicodeString 变量会导致元素可能不是整个字符。如果字符串包含基本多语言平面 (BMP) 中的字符,则所有字符都是 2 个字节,因此对字符串进行索引获取字符。但是,如果某些字符不在 BMP 中,则索引元素可能是代理对,而不是整个字符。

如果我理解正确,S[i] 是字符串的第 i-th 字节的索引。如果SUnicodeString,那么S[1] 是第一个字节,S[2] 是第一个字符的第二个字节,S[3] 是第二个字符的第一个字节,依此类推。如果是这样的话,那么如何索引字符而不是字符串中的字节?我需要索引字符,而不是字节。

【问题讨论】:

  • 不,Delphi中的Unicode“字符”是两个字节,如果Sstring(=UnicodeString在Delphi 2009或更高版本中),S[i]就是这样的两个-byte“字符”。但是只有 BMP 中的 Unicode 字符可以表示为这样的两字节单元,所以S[i] 确实可能只是代理对中的两个部分之一。
  • (在绝大多数应用程序中,您只需要 BMP。它包含数万个字符。不过我不知道您的应用程序。)
  • 所以在像“Test ∫⌬dx ᚭᛘᚠ ቚ꡵씒ᱶⵞꮙ៚ㆯ”这样的简单字符串中,S[i] 是完整的字符。
  • 请在添加标签时添加正确的标签。不要标记delphi-xe2,而是标记delphi-xe3,因为您实际上使用的是Delphi XE3

标签: delphi delphi-xe3


【解决方案1】:

在 Delphi 中,S[i]char 又名 widechar。但这不是 Unicode“字符”,它是 16 位(2 个字节)的 UTF-16 编码值。在上个世纪,即直到 1996 年,Unicode 是 16 位的,但现在已经不是这样了!请仔细阅读Unicode FAQ

您可能需要多个widechar 才能拥有一个完整的Unicode 代码点= 或多或少我们通常所说的“字符”。如果使用变音符号,即使这样也可能是错误的。

UTF-16 使用单个 16 位代码单元对最常见的 63K 字符进行编码,并使用一对 16 位代码单元(称为代理项)对 Unicode 中不常用的 1M 字符进行编码。

最初,Unicode 被设计为纯 16 位编码,旨在 代表所有现代脚本。 (古代脚本是 用私有字符表示。)

随着时间的推移,尤其是 在添加超过 14,500 个复合字符后 与旧集的兼容性,很明显 16 位不是 对于用户社区来说已经足够了。由此产生了 UTF-16。

UTF-16 FAQ

如需正确解码 Delphi 中的 Unicode 代码点,请参阅 Detecting and Retrieving codepoints and surrogates from a Delphi String(@LURD 在 cmets 中的链接)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多