字符串大小比较问题
如下代码:
if AnsiCompareText('1','-')>0 then showmessage('AnsiCompareText:1 大于 -');
if AnsiCompareText('B11-W','B1-W')>0 then showmessage('AnsiCompareText:B11-W 大于 B1-W');
if 'B11-W'>'B1-W' then ShowMessage('>:B11-W 大于 B1-W');
运行结果是:
用AnsiCompareText比较结果:'1'大于'-'
'B11-W'小于'B1-W'
用>比较结果:'B11-W'大于'B1-W'
把我搞晕了,不明白AnsiCompareText的比较机制。请各位兄弟指点迷津。感谢!
解答:
Delphi的操作符比较大小算法就是比较ASCII的大小,ASCII大的就>,有>无的方式来比较的,区分大小写。
AnsiCompareText采取的是Windows API来实现的,调用的是系统的CompareString来实现的,其调用方式如下:
Result := CompareString(LOCALE_USER_DEFAULT, NORM_IGNORECASE, PChar(S1),
Length(S1), PChar(S2), Length(S2)) - 2;
可以看出来是不区分大小写的。查看MSDN的说明,CompareString第二个参数为比较算法指定,默认情况下,如果没有指定某些标志,则就会按系统默认来做的,在Windows中,默认把"-"号作为标点符号进行处理,标点符号是会被忽略的,因此比较上面的数就会出现问题了,可以按下面的方式验证:
比较 B11+W 和 B1+W ,两种方式结果是一样的。
比较 B11W 和 B1W,两种方式是一样的。
说明 - 被系统作为 标点符号处理掉了,可以用下面的方式来验证我们的推测:
function AnsiCompareText(const S1, S2: string): Integer;
begin
{$IFDEF MSWINDOWS}
Result := CompareString(LOCALE_USER_DEFAULT, NORM_IGNORECASE or SORT_STRINGSORT, PChar(S1),
Length(S1), PChar(S2), Length(S2)) - 2;
{$ENDIF}
{$IFDEF LINUX}
Result := WideCompareText(S1, S2);
{$ENDIF}
end;
用上面的AnsiCompareText函数处理的结果就是和Delphi比较结果一致,上面的函数多了一个标志:即把标点符号作为普通符号处理。