次のプログラムは、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 は廃止されたと見なされます。AnsiCompareStr は、http://www.delphibasics.co.uk/RTL.asp?Name=AnsiCompareStr によると、CompareStr の最新の Locale safe 形式であると見なされます。
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;