1

以下程序尝试使用 AnsiCompareStr/Text:

program Project5;
{$APPTYPE CONSOLE}
uses StrUtils, SysUtils;

begin
  Writeln('Ord(''-'')=', Ord('-'));
  Writeln('Ord(''_'')=', Ord('_'));
  Writeln('AnsiCompareStr(''-'', ''_'')=', AnsiCompareStr('-', '_'));
  Writeln('AnsiCompareText(''-'', ''_'')=', AnsiCompareText('-', '_'));
  Writeln('WideCompareStr(''-'', ''_'')=', WideCompareStr('-', '_'));
  Writeln('WideCompareText(''-'', ''_'')=', WideCompareText('-', '_'));
  Writeln('CompareStr(''-'', ''_'')=', CompareStr('-', '_'));
  Writeln('CompareText(''-'', ''_'')=', CompareText('-', '_'));
  Readln;
end.

当用 Kylix 编译时,它在 CentOS 5/6 x64 上输出错误的结果:

Ord('-')=45
Ord('_')=95
AnsiCompareStr('-', '_')=3   <--- should be negative
AnsiCompareText('-', '_')=3  <--- should be negative
WideCompareStr('-', '_')=3   <--- should be negative
WideCompareText('-', '_')=3  <--- should be negative
CompareStr('-', '_')=-50
CompareText('-', '_')=-50

我想知道为什么 AnsiCompareStr/Text 给出错误的结果?

PS:根据http://www.delphibasics.co.uk/RTL.asp?Name=CompareStr,CompareStr被认为是过时的。根据http://www.delphibasics.co.uk/RTL.asp?Name=AnsiCompareStr,AnsiCompareStr被认为是现代的、区域设置安全的 CompareStr 形式。

PS:语言环境是 en_US.iso885915 和/或 en_US.UTF8

PS:Kylix 3(作为带有 CrossKylix 的 Delphi 7)

function AnsiCompareStr(const S1, S2: string): Integer;
begin
{$IFDEF MSWINDOWS}
  Result := CompareString(LOCALE_USER_DEFAULT, 0, PChar(S1), Length(S1),
    PChar(S2), Length(S2)) - 2;
{$ENDIF}
{$IFDEF LINUX}
  // glibc 2.1.2 / 2.1.3 implementations of strcoll() and strxfrm()
  // have severe capacity limits.  Comparing two 100k strings may
  // exhaust the stack and kill the process.
  // Fixed in glibc 2.1.91 and later.
  Result := strcoll(PChar(S1), PChar(S2));
{$ENDIF}
end;

function AnsiCompareText(const S1, S2: string): Integer;
begin
{$IFDEF MSWINDOWS}
  Result := CompareString(LOCALE_USER_DEFAULT, NORM_IGNORECASE, PChar(S1),
    Length(S1), PChar(S2), Length(S2)) - 2;
{$ENDIF}
{$IFDEF LINUX}
  Result := WideCompareText(S1, S2);
{$ENDIF}
end;
4

1 回答 1

3

AnsiCompareStr/Text正在给出正确的结果。它们反映了主要地区定义的顺序。例如,通过对 glibc 标准库AnsiCompareStr的简单调用来实现。strcoll

问题在于你的期望。我不确定您为什么期望得到您所做的结果,但是期望glibc正确实现排序规则是很合理的。隐含的strcoll顺序是流行语言环境的整理顺序,无论发生什么。你没有在问题中说明这一点。

也许线索是您使用了短语locale safe。好吧,CompareXXX都独立于语言环境,AnsiCompareXXX取决于语言环境。如果您正在寻找区域设置不变的顺序,那么AnsiCompareXXX这是错误的选择。

于 2015-10-28T13:00:15.063 回答