我找到了一个执行“自然比较”功能的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;

我对字符编码知之甚少,所以这就是我提问的原因。这个函数是OK还是我应该先以某种方式转换两个比较的字符串?

有帮助吗?

解决方案

请记住,将字符串转换为WideString会使用默认系统代码页转换它,这可能是您需要的,也可能不是。通常,您需要使用当前用户的区域设置。

来自System.pas中的 WCharFromChar

Result := MultiByteToWideChar(DefaultSystemCodePage, 0, CharSource, SrcBytes,
  WCharDest, DestChars);

您可以通过调用 SetMultiByteConversionCodePage <来更改DefaultSystemCodePage / A>

其他提示

您的函数可能有一个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