(delphi11最新学习资料) Object Pascal 学习笔记---第6章第4节(字符串及编码 )

6.4 字符串及编码

​ 正如我们所看到的,Object Pascal中的字符串类型映射到Unicode UTF-16格式,每个元素2字节,并管理BMP(基本多语言平面)之外码点的代理对。

​ 但是,在许多情况下,您需要保存到文件、从文件加载、通过套接字连接传输或从使用不同表示形式(如ANSI或UTF-8)的连接接收文本数据。

​ 要在不同格式(或编码)之间转换文件和内存数据,Object Pascal RTL 有一个名为 TEncoding 类,与它几个继承类一起定义在 System.SysUtils 单元中。

注解: Object Pascal RTL 中还有其他几个便利类,可以用来读写文本格式的数据。例如,TStreamReader 和 TStreamWriter 类支持任何编码的文本文件。这些类将在第 18 章中介绍。

​ 虽然我还没有介绍类和继承,但这组编码类非常易于使用,因为每种编码都有一个全局对象可供使用。

​ 换句话说,在 TEncoding 类中,每个编码类的对象都可以作为类属性使用:

type
   TEncoding = class
   ... public
      class property ASCII: TEncoding read GetASCII;
      class property BigEndianUnicode: TEncoding read GetBigEndianUnicode;
      class property Default: TEncoding read GetDefault;
      class property Unicode: TEncoding read GetUnicode;
      class property UTF7: TEncoding read GetUTF7;
      class property UTF8: TEncoding read GetUTF8;

注解:Unicode 编码基于 TUnicodeEncoding 类,该类使用与字符串类型相同的 UTF-16 LE(小端)格式。而 BigEndianUnicode 使用的是不常用的 Big Endian 表示法。如果你不熟悉 “端点”(endianness),这是一个术语,用于表示构成一个码点(或任何其他数据结构)的两个字节的顺序。小端表示最高有效字节在前,大端表示最高有效字节在后。更多信息,请参见 en.wikipedia.org/wiki/Endianness。

​ 同样,本书在这个阶段,与其泛泛地探讨这些类(这有点困难),不如让我们关注几个实际的例子。TEncoding 类拥有将 Unicode 字符串读写到字节数组以及执行适当转换的方法。

​ 为了演示通过 TEncoding 类进行 UTF 格式转换,同时也为了使示例简单明了,避免与文件系统打交道,在 EncodingsTest 示例中,我使用一些特定数据在内存中创建了一个 UTF-8 字符串,并通过一次函数调用将其转换为 UTF-16:

var
   Utf8String: TBytes;
   Utf16String: string;
begin
   // 处理UTF-8数据
   SetLength(Utf8String, 3);
   Utf8String[0] := Ord('a'); // 单字节ANSI字符 < 128
   Utf8String[1] := $c9; // 双字节,反转的拉丁字母a
   Utf8String[2] := $90;

   Utf16String := TEncoding.UTF8.GetString(Utf8String);
   Show('Unicode: ' + Utf16String);

​ 输出应为:

Unicode: aɐ

​ 为了更好地理解转换以及表示形式之间的差异,我添加了以下代码:

Show('Utf8 bytes:');
for AByte in Utf8String do
   Show(AByte.ToString);

Show('Utf16 bytes:');
UniBytes := TEncoding.Unicode.GetBytes(Utf16String);
for AByte in UniBytes do
   Show(AByte.ToString);

​ 这段代码会产生一个内存转储,其中包含字符串两种表示形式的十进制值: UTF-8(一个字节和两个字节的码点)和 UTF-16(两个码点均为 2 个字节):

97
201
144
Utf16 bytes:
97
0
80
2

请注意,UTF-8 字符到字节的直接转换只适用于 ANSI-7 字符,即最大值为 127 的字符。对于更高级别的 ANSI 字符,没有直接的映射,必须使用特定的编码进行转换(然而,对于多字节的 UTF-8 元素,转换将失败)。因此,以下两种情况都会产生错误的输出结果:

// 错误:无法使用char > 128
Utf8String[0] := Ord('à');
Utf16String := TEncoding.UTF8.GetString(Utf8String);
Show('Wrong high ANSI: ' + Utf16string);

// 尝试不同的转换
Utf16String := TEncoding.ANSI.GetString(Utf8String);
Show('Wrong double byte: ' + Utf16String);

输出

// Output
Wrong high ANSI:
Wrong double byte: àÉ

编码类允许您进行双向转换;因此,在本例中,我在将 UTF-16 转换为 UTF-8 时,对 UTF-8 字符串进行了一些处理(鉴于这种格式的长度可变,因此要小心谨慎),然后将其转换回 UTF-16:

var
   Utf8String: TBytes;
   Utf16String: string;
   I: Integer;
begin
   Utf16String := 'This is my nice string with à and Æ';
   Show('Initial: ' + Utf16String);

   Utf8String := TEncoding.UTF8.GetBytes(Utf16String); for I := 0 to High(Utf8String) do
            if Utf8String[I] = Ord('i') then
              Utf8String[I] := Ord('I');
	Utf16String := TEncoding.UTF8.GetString(Utf8String); 
	Show('Final: ' + Utf16String);

输出如下:

Initial: This is my nice string with à and Æ
Final: ThIs Is my nIce strIng wIth à and Æ
  • 17
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Delphi7是一种非常受欢迎的编程语言和集成开发环境,它在处理字符串时并不直接支持UTF-8编码。在Delphi7中,字符串类型默认为AnsiString,它使用ANSI字符集来表示字符。 要在Delphi7中使用UTF-8编码字符串,需要进行一些额外的处理。首先,您需要使用Third Party Libraries(第三方库)来提供对UTF-8字符串的支持。例如,您可以使用JEDI Code Library或TntUnicodeControls库。 在使用这些库之后,您就可以在Delphi7中处理UTF-8字符串了。您可以使用TntUnicodeString类型来存储和处理UTF-8字符串。TntUnicodeString是一个Unicode字符串类型,可以存储任意Unicode字符,包括UTF-8编码的字符。 当您需要操作UTF-8字符串时,可以使用TntUnicodeString提供的函数和方法来进行处理。例如,您可以使用TntUnicodeString的Length函数来获取UTF-8字符串的长度,使用TntUnicodeString的Copy函数来复制UTF-8字符串的一部分,使用TntUnicodeString的Pos函数来查找子字符串在UTF-8字符串中的位置等等。 需要注意的是,使用UTF-8字符串可能会增加内存和处理的开销。因为UTF-8编码使用变长编码,所以处理和操作UTF-8字符串需要更多的计算。此外,还需要在将UTF-8字符串显示在用户界面中时进行适当的编码转换,以确保正确显示。 总之,在Delphi7中使用UTF-8字符串需要使用第三方库来提供对UTF-8字符串的支持,并使用TntUnicodeString类型来存储和处理UTF-8字符串。尽管增加了一些额外的处理,但这样可以确保您能够处理和操作UTF-8编码字符串
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值