===============================================
20110919 수정사항 추가
else if Str1[Pos1] = #0 then
begin
Result := 0;
Exit;
end
에셔 결과값 0을 -1로 변경해야함.
================================================
---------
a - 1
a - 10
a - 99
a - 9
a - 10000
---------
위와 같은 데이터가 있을때
델파이의 CompareStr로 비교하면
---------
a - 1
a - 10
a - 10000
a - 9
a - 99
---------
로 나옵니다.
윈도우탐색기에서 입력해보면
--------
a - 1
a - 9
a - 10
a - 99
a - 10000
--------
으로 정렬됩니다.
출처는 http://www.scottandmichelle.net/scott/code/index2.mv?codenum=100 입니다.
씨 소스로 되어있길래 포팅해봤습니다.
function NaturalOrderCompareString( const A1, A2: string; ACaseSensitive: Boolean ): Integer;
var
Str1, Str2: PChar;
Pos1, Pos2: Integer;
EndPos1, EndPos2: Integer;
begin
Str1 := PChar(A1);
Str2 := PChar(A2);
Pos1 := -1;
Pos2 := -1;
while True do
begin
Inc( Pos1 );
Inc( Pos2 );
if (Str1[Pos1] = #0) and (Str2[Pos2] = #0) then
begin
Result := 0;
Exit;
end
else if Str1[Pos1] = #0 then
begin
Result := -1;
Exit;
end
else if Str2[Pos2] = #0 then
begin
Result := 1;
Exit;
end;
if (Str1[Pos1] >= '0') and (Str1[Pos1] <= '9') and
(Str2[Pos2] >= '0') and (Str2[Pos2] <= '9') then
begin
EndPos1 := Pos1;
repeat
Inc(EndPos1);
until not ((Str1[EndPos1] >= '0') and (Str1[EndPos1] <= '9'));
EndPos2 := Pos2;
repeat
Inc(EndPos2);
until not ((Str2[EndPos2] >= '0') and (Str2[EndPos2] <= '9'));
while True do
begin
if EndPos1 - Pos1 = EndPos2 - Pos2 then
begin
// 이부분이 숫자비교임. StrToInt 한 다음에 빼도 될 것임
Result := CompareStr( Copy(Str1, Pos1+1, EndPos1 - Pos1), Copy(Str2, Pos2+1, EndPos1 - Pos1) ) ;
if Result = 0 then
begin
Pos1 := EndPos1 - 1;
Pos2 := EndPos2 - 1;
Break;
end
else
begin
Exit;
end;
end
else if EndPos1 - Pos1 > EndPos2 - Pos2 then
begin
if Str1[Pos1] = '0' then
Inc(Pos1)
else
begin
Result := 1;
Exit;
end;
end
else
begin
if Str2[Pos2] = '0' then
Inc( Pos2 )
else
begin
Result := -1;
Exit;
end;
end;
end;
end
else
begin
if ACaseSensitive then
Result := CompareStr( Copy(Str1, Pos1, 1), Copy(Str2, Pos2, 1) )
else
Result := CompareText( Copy(Str1, Pos1, 1), Copy(Str2, Pos2, 1) );
if Result <> 0 then
Exit;
end;
end;
end;
리스트뷰 OnCompare에 델파이의 CompareStr, NaturalOrderCompareString 함수, Windows 유닛 내의 CompareString 함수로 정렬해서 비교한 간단한 예제가 있으니 비교해보시기 바랍니다.
정렬부분 소스는
procedure TForm3.ListView1Compare(Sender: TObject; Item1, Item2: TListItem;
Data: Integer; var Compare: Integer);
var
CompareResult: Integer;
begin
case ComboBox1.ItemIndex of
0:
begin
// Na
Compare := NaturalOrderCompareString( Item1.Caption, Item2.Caption, True );
end;
1:
begin
// 일반 문자열 비교
Compare := CompareStr( Item1.Caption, Item2.Caption );
end;
2:
begin
// Window API
CompareResult := CompareString( LOCALE_USER_DEFAULT, 0, PChar(Item1.Caption), Length(Item1.Caption), PChar(Item2.Caption), Length(Item2.Caption) );
case CompareResult of
CSTR_LESS_THAN: Compare := -1;
CSTR_GREATER_THAN: Compare := 1;
CSTR_EQUAL: Compare := 0;
end;
end;
end;
end;
'Programming > Delphi' 카테고리의 다른 글
Delphi - TOpenDialog쓰면서 FileExists로 왜 체크해요? (0) | 2010.03.14 |
---|---|
Delphi - TArray<T>의 Sort 및 BinarySearch (2) | 2010.02.22 |
Delphi - class의 private, protected에 strict를 추가해보자. (4) | 2010.01.29 |
Delphi - 클래스 내에 const 사용하기 (0) | 2010.01.27 |
Delphi - Generic중 유용한 TObjectList<T>에 ToArray를 추가해보자 (6) | 2010.01.21 |