Delphiで文字列をWideStringに変換する必要がありますか?
-
06-07-2019 - |
質問
「自然な比較」を実行するWindows API関数を見つけました。文字列の。次のように定義されています。
int StrCmpLogicalW(
LPCWSTR psz1,
LPCWSTR psz2
);
Delphiで使用するには、次のように宣言しました。
interface
function StrCmpLogicalW(psz1, psz2: PWideChar): integer; stdcall;
implementation
function StrCmpLogicalW; external 'shlwapi.dll' name 'StrCmpLogicalW';
Unicode の文字列を比較するため、どのように呼び出すかわからないANSI文字列を比較したい。文字列をWideStringにキャストしてからPWideCharにキャストするだけで十分のようですが、このアプローチが正しいかどうかはわかりません。
function AnsiNaturalCompareText(const S1, S2: string): integer;
begin
Result := StrCmpLogicalW(PWideChar(WideString(S1)), PWideChar(WideString(S2)));
end;
文字エンコードについてほとんど知らないので、これが私の質問の理由です。この関数は大丈夫ですか、それとも最初に比較した文字列を何らかの方法で変換する必要がありますか?
解決
文字列をWideStringにキャストすると、デフォルトのシステムコードページを使用して変換されることに注意してください。通常、現在のユーザーのロケールを使用します。
System.pasの WCharFromChar
から:
Result := MultiByteToWideChar(DefaultSystemCodePage, 0, CharSource, SrcBytes,
WCharDest, DestChars);
SetMultiByteConversionCodePage <を呼び出すことにより、DefaultSystemCodePageを変更できます。 / a>。
他のヒント
タスクを達成する簡単な方法は、関数を次のように宣言することです。
interface
function StrCmpLogicalW(const sz1, sz2: WideString): Integer; stdcall;
implementation
function StrCmpLogicalW; external 'shlwapi.dll' name 'StrCmpLogicalW';
WideString
変数 は WideChar
へのポインタであるため( AnsiString
変数< em>は AnsiChar
へのポインタです。)
この方法で、Delphiは自動的に「アップコンバート」しますAnsiStringを WideString
に変換します。
更新
そして、今は UnicodeString
の世界にいるので、あなたはそれを作るでしょう:
interface
function StrCmpLogicalW(const sz1, sz2: UnicodeString): Integer; stdcall;
implementation
function StrCmpLogicalW; external 'shlwapi.dll' name 'StrCmpLogicalW';
UnicodeString
変数は、 WideChars
の \ 0 \ 0
終了文字列へのポインタであるためです。呼び出した場合:
var
s1, s1: AnsiString;
begin
s1 := 'Hello';
s2 := 'world';
nCompare := StrCmpLogicalW(s1, s2);
end;
UnicodeString
を受け取る関数に AnsiString
を渡そうとすると、コンパイラは生成されたもので MultiByteToWideChar
を自動的に呼び出しますコード。
CompareStringは、Windows 7で数値の並べ替えをサポートしています
Windows 7以降では、Microsoftは SORT_DIGITSASNUMBERS
を CompareString
:
Windows 7:ソート中に数字を数字として扱います。たとえば、&quot; 2&quot;をソートします。 &quot; 10&quot;の前。
これらのいずれも、文字列を変換またはキャストする必要がある場合に対処する実際の質問への回答には役立ちません。
関数のANSIバリアントがあるかもしれません(私はチェックしていません)。ほとんどのWide APIもANSIバージョンとして利用できます。WサフィックスをAに変更するだけで設定できます。その場合、Windowsはあなたのために透明な変換を行います。
PS:StrCmpLogicalAの欠如を説明する記事は次のとおりです。 http://blogs.msdn.com/joshpoley/archive/2008/04/28/strcmplogicala.aspx
System.StringToOleStr
を使用します。 MultiByteToWideChar
の便利なラッパーです。 Gabrの答えを参照してください:
function AnsiNaturalCompareText(const S1, S2: string): integer;
var
W1: PWideChar;
W2: PWideChar;
begin
W1 := StringToOleStr(S1);
W2 := StringToOleStr(S2);
Result := StrCmpLogicalW(W1, W2);
SysFreeString(W1);
SysFreeString(W2);
end;
しかし、 Ian Boydのソリューションは見栄えが良く、はるかに優れています!