【问题标题】:Can Delphi 6 convert UTF-8 Portuguese to WideString?Delphi 6 可以将 UTF-8 葡萄牙语转换为 WideString 吗?
【发布时间】:2017-10-04 08:36:23
【问题描述】:

我正在使用 Delphi 6。

我想将葡萄牙语 UTF-8 编码的字符串解码为 WideString,但我发现它没有正确解码。

原文为"ANÁLISE8"。使用UTF8Decode()后,结果为"ANALISE8""A" 顶部的符号消失。

代码如下:

var
  f : textfile;
  s : UTF8String;
  w, test : WideString;    
begin
  while not eof(f) do
  begin
    readln(f,s);
    w := UTF8Decode(s);

如何将葡萄牙语 UTF-8 字符串正确解码为 WideString

【问题讨论】:

  • 使用 MultiByteToWideChar
  • 您的文件可能不是用 UTF-8 编写的。以 UTF-8 编写的文件通常在前面有 3 字节 byte-order-mark sequence,如果文件没有,则可以安全地假定它使用系统的默认 Ansi 代码页。在这种情况下,将数据存储在 UTF8String 中不会 使 UTF-8...
  • 您是如何确定您的代码不起作用的。我敢打赌,您将 WideString 转换为 ANSI。
  • @StijnSanders:“以 UTF-8 编写的文件通常前面有 3 字节字节顺序标记序列” - 实际上,它们没有,因为Unicode 和 UTF-8 规范不鼓励人们将 BOM 与 UTF-8 编码文件一起使用,以向后兼容 ASCII 文本文件和不知道如何处理 BOM 的旧版应用程序。 可以 BOM 存在于 UTF-8 文件中吗?是的。 是否 BOM 存在于 UTF-8 文件中?通常不会,大多数时候。
  • 奇怪。 我遇到的每个 UTF-8 文件都有一个BOM,我的尝试不这样做会导致麻烦......但我想每个人的里程可能会有所不同。

标签: delphi unicode utf-8 delphi-6


【解决方案1】:

请注意,UTF8Decode() 在 Delphi 6 中的实现是不完整的。具体来说,它不支持编码的 4 字节序列,这是处理U+FFFF 以上的 Unicode 代码点所必需的。这意味着UTF8Decode() 只能解码 UCS-2 范围内的 Unicode 代码点,而不是完整的 Unicode 曲目。因此,UTF8Decode() 在 Delphi 6 中基本上没用(一直到 Delphi 2007 - 它最终在 Delphi 2009 中得到修复)。

尝试改用 Win32 MultiByteToWideChar() 函数,例如:

uses
  ..., Windows;

function MyUTF8Decode(const s: UTF8String): WideString;
var
  Len: Integer;
begin
  Len := MultiByteToWideChar(CP_UTF8, 0, PAnsiChar(s), Length(s), nil, 0);
  SetLength(Result, Len);
  if Len > 0 then
    MultiByteToWideChar(CP_UTF8, 0, PAnsiChar(s), Length(s), PWideChar(Result), Len));
end;

var
  f : textfile;
  s : UTF8String;
  w, test : WideString;
begin
  while not eof(f) do
  begin
    readln(f,s);
    w := MyUTF8Decode(s);

话虽如此,您的ANÁLISE8 字符串在UCS-2 范围内,所以我在Delphi 6 中测试了UTF8Decode(),它解码了ANÁLISE8 的UTF-8 编码形式就好了。我的结论是:

  • 您的 UTF8String 变量不包含开头的 ANÁLISE8 的 UTF-8 编码形式(字节序列 41 4E C3 81 4C 49 53 45 38),而是包含 ASCII 字符串 ANALISE8(字节序列 @987654334 @),它将按原样解码,因为 ASCII 是 UTF-8 的子集。仔细检查您的文件,以及Readln() 的输出。

  • 1234563 /p>

【讨论】:

  • 嗨,非常感谢,我只是将 UTF-8 代码转换为 HEX 并查看(字节序列 41 4E C3 81 4C 49 53 45 38),所以我认为文件必须是 UTF -8 格式...感谢 MyUTF8Decode 函数,只是用它代替了 UTF8Decode 结果是一样的,葡萄牙字符变成英文
  • @JohnKen 那么问题一定与你在解码后对数据所做的任何事情有关。无论您在做什么,都将其转换为 ANSI/ASCII。
  • 那么我怎样才能将其转换为 UTF8String :P ..... 或将其存储为 UTF8 宽字符串
  • @JohnKen 您验证了 file 包含正确的 UTF-8 字节。您是否(使用调试器)验证 UTF8String 包含相同的字节?如果是这样,那么Readln() 没有转换数据,那么您是否(使用调试器)验证WideString 包含正确的解码字符? 0041 004E 00C1 004C 0049 0053 0045 0038。如果是这样,那么WideString 很好(MultiByteToWideChar() 没有损坏)。您对WideString 解码后所做的就是将数据转换为 ANSI/ASCII。您还没有显示任何代码。
猜你喜欢
  • 2019-04-10
  • 1970-01-01
  • 1970-01-01
  • 2016-01-15
  • 1970-01-01
  • 1970-01-01
  • 2019-11-11
  • 2019-05-26
  • 1970-01-01
相关资源
最近更新 更多