如何在UTF-8中将WideString(或其他长字符串)转换为字节数组?
答案 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并直接转到字节数组;只需将返回类型更改为TBytes
或array 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的评论。