UTF-8中的字符串到字节数组?

Mar*_*usz 8 freepascal utf-8 lazarus

如何在UTF-8中将WideString(或其他长字符串)转换为字节数组?

Dav*_*nan 12

这样的功能可以满足您的需求:

function UTF8Bytes(const s: UTF8String): TBytes;
begin
  Assert(StringElementSize(s)=1);
  SetLength(Result, Length(s));
  if Length(Result)>0 then
    Move(s[1], Result[0], Length(s));
end;
Run Code Online (Sandbox Code Playgroud)

您可以使用任何类型的字符串调用它,RTL将从传递给UTF-8的字符串的编码转换.所以不要误以为你必须在调用之前转换为UTF-8,只需传入任何字符串并让RTL完成工作.

之后,它是一个相当标准的阵列副本.请注意显式调用UTF-8编码字符串的字符串元素大小的假设的断言.

如果你想获得零终止符,你可以这样写:

function UTF8Bytes(const s: UTF8String): TBytes;
begin
  Assert(StringElementSize(s)=1);
  SetLength(Result, Length(s)+1);
  if Length(Result)>0 then
    Move(s[1], Result[0], Length(s));
  Result[high(Result)] := 0;
end;
Run Code Online (Sandbox Code Playgroud)


Mik*_*son 8

您可以TEncoding.UTF8.GetBytes在SysUtils.pas中使用

  • 请注意,如果输入字符串*已经*编码为UTF-8,那么`GetBytes`将非常浪费.编译器将输入字符串转换为UnicodeString,因为这是唯一的字符串参数`GetBytes`允许,而`GetBytes`将字符转换回UTF-8以生成其结果. (5认同)

Rob*_*edy 5

如果您使用的是Delphi 2009或更高版本(Unicode版本),则将WideString转换为UTF8String是一个简单的赋值语句:

var
  ws: WideString;
  u8s: UTF8String;

u8s := ws;
Run Code Online (Sandbox Code Playgroud)

编译器将调用正确的库函数来进行转换,因为它知道UTF8String类型的值具有"代码页" CP_UTF8.

在Delphi 7及更高版本中,您可以使用提供的库函数Utf8Encode.对于更早的版本,您可以从其他库(例如JCL)获取该功能.

您还可以使用Windows API编写自己的转换函数:

function CustomUtf8Encode(const ws: WideString): UTF8String;
var
  n: Integer;
begin
  n := WideCharToMultiByte(cp_UTF8, 0, PWideChar(ws), Length(ws), nil, 0, nil, nil);
  Win32Check(n <> 0);
  SetLength(Result, n);
  n := WideCharToMultiByte(cp_UTF8, 0, PWideChar(ws), Length(ws), PAnsiChar(Result), n, nil, nil);
  Win32Check(n = Length(Result));
end;
Run Code Online (Sandbox Code Playgroud)

很多时候,你可以简单地使用UTF8String作为数组,但如果你真的需要一个字节数组,你可以使用David和Cosmin的函数.如果您正在编写自己的字符转换函数,则可以跳过UTF8String并直接转到字节数组; 只需将返回类型更改为TBytesarray of Byte.(如果希望数组以空值终止,您可能还希望将长度增加一个.SetLength将隐式地对字符串执行此操作,但对数组执行此操作.)

如果你有一些既不是WideString,UnicodeString也不是UTF8String的其他字符串类型,那么将它转换为UTF-8的方法是首先将其转换为WideString或UnicodeString,然后将其转换回UTF-8.