WideString(または他の長い文字列)をUTF-8でバイト配列に変換するにはどうすればよいですか?
6 に答える
このような関数は、必要なことを行います:
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;
TEncoding.UTF8.GetBytes
SysUtils.pas で使用できます
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
orに変更するだけarray of Byte
です。(配列をヌルで終了させたい場合は、長さを 1 増やしたい場合もあります。SetLength は暗黙的に文字列に対してそれを行いますが、配列に対して行います。)
WideString、UnicodeString、UTF8String のいずれでもない他の文字列型がある場合、それを UTF-8 に変換する方法は、まずそれを WideString または UnicodeString に変換してから、UTF-8 に戻すことです。
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 を追加すると、サンプルが読みにくくなります。
次の 2 つのルーチンがあります (ソース コードはhttp://www.csinnovations.com/framework_utilities.htmからダウンロードできます)。
function CsiBytesToStr(const pInData: TByteDynArray; pStringEncoding: TECsiStringEncoding; pIncludesBom: Boolean): 文字列;
function CsiStrToBytes(const pInStr: string; pStringEncoding: TECsiStringEncoding; pIncludeBom: Boolean): TByteDynArray;
ワイドストリング -> 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 の発言を参照してください。