質問

「自然な比較」を実行する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のソリューションは見栄えが良く、はるかに優れています!

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top