是否有必要字符串转换为WideString的德尔福?(Is it necessary to conv

2019-06-23 18:58发布

我发现,执行字符串的“自然比较” 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功能或者我应该先以某种方式转换都比较字符串?

Answer 1:

请记住,铸造一个字符串转换为WideString的使用将默认系统代码页可能会或可能不会是你所需要的转换。 通常情况下,你想使用当前用户的语言环境。

WCharFromChar在System.pas:

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

你可以通过调用改变DefaultSystemCodePage SetMultiByteConversionCodePage 。



Answer 2:

完成该任务的更简单的方法是声明你的功能:

interface
   function StrCmpLogicalW(const sz1, sz2: WideString): Integer; stdcall;

implementation
   function StrCmpLogicalW; external 'shlwapi.dll' name 'StrCmpLogicalW';

因为一个WideString变量指向一个WideChar (以同样的方式的AnsiString变量指向一个AnsiChar 。)

而这样一来Delphi会自动“向上转换”的AnsiString类型的WideString为您服务。

更新

而且,由于我们的世界现在已经UnicodeString ,你会做它:

interface
   function StrCmpLogicalW(const sz1, sz2: UnicodeString): Integer; stdcall;

implementation
   function StrCmpLogicalW; external 'shlwapi.dll' name 'StrCmpLogicalW';

因为一个UnicodeString变量仍然是一个指针,指向一个\0\0的终止字符串WideChars 。 所以,如果你拨打:

var
    s1, s1: AnsiString;
begin
    s1 := 'Hello';
    s2 := 'world';

    nCompare := StrCmpLogicalW(s1, s2);
end;

当您尝试通过一个AnsiString成需要的功能UnicodeString ,编译器会自动调用MultiByteToWideChar在生成的代码为您服务。

CompareString支持数字排序在Windows 7

在Windows 7开始,微软添加SORT_DIGITSASNUMBERSCompareString

视窗7:“10”之前,在排序过程中对待位数字,例如,排序“2”。

这一切都不有助于回答的实际问题,这与当你不得不转换或铸造字符串交易。



Answer 3:

有可能是一个ANSI变种作为你的功能(我没有检查)。 最全的API可作为一个ANSI版本太多,只是改变后缀W到A,和你设置。 Windows不会背的反复转换transparantly你在这种情况下。

PS:这里的描述缺乏StrCmpLogicalA的文章: http://blogs.msdn.com/joshpoley/archive/2008/04/28/strcmplogicala.aspx



Answer 4:

使用System.StringToOleStr ,这大约是一个方便的包装MultiByteToWideChar ,看到贾布尔的回答 :

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;

但后来, 伊恩·博伊德的解决方案看起来是好得多!



文章来源: Is it necessary to convert string to WideString in Delphi?