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

时间:2011-03-08 14:01:18

标签: utf-8 lazarus freepascal

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

6 个答案:

答案 0 :(得分: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;

您可以使用任何类型的字符串调用它,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;

答案 1 :(得分:8)

您可以在SysUtils.pas

中使用TEncoding.UTF8.GetBytes

答案 2 :(得分:5)

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

var
  ws: WideString;
  u8s: UTF8String;

u8s := ws;

编译器将调用正确的库函数来执行转换,因为它知道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;

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

如果您有其他字符串类型既不是WideString,也不是UnicodeString,也不是UTF8String,那么将其转换为UTF-8的方法是首先将其转换为WideString或UnicodeString,然后将其转换回UTF-8。 / p>

答案 3 :(得分:4)

var S: UTF8String;
    B: TBytes;

begin
  S := 'Șase sași în șase saci';
  SetLength(B, Length(S)); // Length(s) = 26 for this 22 char string.
  CopyMemory(@B[0], @S[1], Length(S));
end.

根据您需要的字节数,您可能希望包含一个NULL终止符。

对于生产代码,请确保测试空字符串。添加3-4 LOC只会使样品难以读取。

答案 4 :(得分:1)

我有以下两个例程(源代码可以在这里下载 - http://www.csinnovations.com/framework_utilities.htm):

function CsiBytesToStr(const pInData:TByteDynArray; pStringEncoding:TECsiStringEncoding; pIncludesBom:Boolean):string;

function CsiStrToBytes(const pInStr:string; pStringEncoding:TECsiStringEncoding;  pIncludeBom:Boolean):TByteDynArray;

答案 5 :(得分:0)

widestring - &gt; UTF8:

http://www.freepascal.org/docs-html/rtl/system/utf8decode.html

相反的是:

http://www.freepascal.org/docs-html/rtl/system/utf8encode.html

请注意,在D2009之前的系统(包括当前的Free Pascal)中为一个ansistring分配一个宽字符串将转换为本地ansi编码,使字符变为乱码。

对于TBytes部分,请参阅上面Rob Kennedy的评论。