我准备了一些来自 Delphi 建议的代码片段,没有编译器警告或隐式转换,但结果不满意我。
procedure Convert;
type
TUTF8Buf = array [0 .. 5] of byte;
var
s: string;
sutf8: UTF8String; // manageable UTF-8 string
utf8str: TUTF8Buf; // unmanageable buffer
begin
utf8str := Default (TUTF8Buf); // utf8str = (0,0,0,0,0,0)
s := UTF8ArrayToString(utf8str); // s = #0#0#0#0#0#0
s := 'abc'; // s = 'abc'
sutf8 := UTF8Encode(s); // sutf8 = 'abc'
Move(sutf8[1], utf8str[0], Min(Length(sutf8), sizeof(utf8str) - 1)); // utf8str = (97, 98, 99, 0, 0)
s := UTF8ArrayToString(utf8str); // s = 'abc'#0#0#0
s := UTF8ToString(sutf8); // s = 'abc'
end;
这段代码在处理可管理的UTF-8字符串时工作得非常好,但在处理不可管理的缓冲区时总是产生尾随的零。
2条答案
按热度按时间fnvucqvd1#
UTF8ArrayToString()
函数将整个数组作为一个整体进行转换,如果遇到$0
字节,它不会停止。您应该使用不同的例程来指定数组中需要转换的字节数,例如Utf8ToUnicode()
、UnicodeFromLocaleChars()
或TEncoding.UTF8.GetChars()
。也就是说,处理UTF-8最简单的方法就是使用
UTF8String
本身。RTL知道如何在UnicodeString
和UTF8String
之间进行隐式转换,让它来为你做这项工作。你不需要UTF8Encode()
和UTF8Decode()
,因为它们自2009年以来已经被弃用。okxuctiv2#
UTF8String
中的字符长度可变,但#$00
-#$7F
不会出现在多字节字符中。因此,就像AnsiString
一样,您可以通过扫描x1m4 n1.来确定长度。StrLen
(在最近的版本中移到了AnsiString
单元)会为您完成此操作。注:应该工作,但我还没有测试它。