在Delphi中将UTF8转换为ANSI(ISO-8859-1)

4

我有一个问题,要将UTF8字符串转换为ANSI字符串。我的代码能够处理元音字母的重音符号,但是对于字母Ñ则无法正常工作。代码会打断字符串。我该如何修复这个错误?

我在UTF8中拥有的字符串是: EDIFICIO PEÑAS BLANCAS
如果正确的话,我应该拥有的ANSI字符串是: EDIFICIO PEÑAS BLANCAS
但现在我所拥有的ANSI字符串是: EDIFICIO PE

以下是我的代码:

    function TFormMain.convertir_utf8_ansi(const Source: string):string;
    var
       Iterator, SourceLength, FChar, NChar: Integer;
    begin
       Result := '';
       Iterator := 0;
       SourceLength := Length(Source);
       while Iterator < SourceLength do
       begin
          Inc(Iterator);
          FChar := Ord(Source[Iterator]);
          if FChar >= $80 then
          begin
             Inc(Iterator);
             if Iterator > SourceLength then break;
             FChar := FChar and $3F;
             if (FChar and $20) <> 0 then
             begin
                FChar := FChar and $1F;
                NChar := Ord(Source[Iterator]);
                if (NChar and $C0) <> $80 then break;
                FChar := (FChar shl 6) or (NChar and $3F);
                Inc(Iterator);
                if Iterator > SourceLength then break;
             end;
             NChar := Ord(Source[Iterator]);
             if (NChar and $C0) <> $80 then break;
             Result := Result + WideChar((FChar shl 6) or (NChar and $3F));
          end
          else
             Result := Result + WideChar(FChar);
       end;
    end;

谢谢。


1
Delphi是哪个版本?最优解取决于它。请添加适当的标签。 - Jan Doggen
2
你拥有的第一个字符串没有以UTF-8格式显示。它是UTF-8编码的字节被解释为其他东西,可能是ISO-8859-1或Windows-1252。如果一开始就将UTF-8字节解释为UTF-8,你很可能不会遇到这个问题。你应该调查Source来自哪里以及为什么出错了。 - Rob Kennedy
1
听起来你可能问错了问题,陷入了经典的XY问题。 - David Heffernan
2个回答

14

如果您使用的是Delphi 2009或更高版本,则应该让RTL为您进行转换:

type
  Latin1String = type AnsiString(28591); // codepage 28591 = ISO-8859-1
var
  utf8: UTF8String;
  latin1: Latin1String;
begin
  utf8 := ...; // your source UTF-8 string
  latin1 := Latin1String(utf8);
end;

如果您正在使用Delphi 2007或更早版本,您仍然可以进行转换,只需让操作系统为您完成:

var
  utf8: UTF8String;
  latin1: AnsiString;
  ws: WideString;
  len: Integer;
begin
  utf8 := ...; // your source UTF-8 string
  len := MultiByteToWideChar(CP_UTF8, 0, PAnsiChar(utf8), Length(utf8), nil, 0);
  SetLength(ws, len);
  MultiByteToWideChar(CP_UTF8, 0, PAnsiChar(utf8), Length(utf8), PWideChar(ws), len);
  len := WideCharToMultiByte(28591, 0, PWideChar(ws), Length(ws), nil, 0, nil, nil);
  SetLength(latin1, len);
  WideCharToMultiByte(28591, 0, PWideChar(ws), Length(ws), PAnsiChar(latin1), len, nil, nil);
end;

5

我解决了调用问题,除了我的功能之外,还使用了内部函数UTF8toAnsi。我正在使用Delphi 2010进行开发。

方法如下: Utf8toAnsi(convertir_utf8_ansi(source));


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接