Zahlen mit führenden Blanks werden anders sortiert als Zahlen mit führenden Nullen.
Beispiel1:
Code: Alles auswählen
' 13'
' 14'
' 6'
Code: Alles auswählen
' 06'
' 13'
' 14'
Code: Alles auswählen
' 13'
' 14'
' 6'
Code: Alles auswählen
' 06'
' 13'
' 14'
Der Grund dafür ist, das es der normalen Sortierfunktion egal ist ob es sich um eine Ziffer handelt. Diese sortiert einfach nach den ASCII-Zeichen, und Space ist kleiner als die Ziffern.Zahlen mit führenden Blanks werden anders sortiert als Zahlen mit führenden Nullen.
Code: Alles auswählen
sl.Add(' 13');
sl.Add(' 14');
sl.Add(' 11');
sl.Add(' 6');
sl.Add(' 5');
sl.Add(' 05');
sl.Sort;
ShowMessage(sl.Text); \0
Code: Alles auswählen
05
11
13
14
5
6
Code: Alles auswählen
sl.Add(' 13');
sl.Add(' 14');
sl.Add(' 11');
sl.Add(' 6');
sl.Add(' 5');
sl.Add(' 05');
sl.Add('##13');
sl.Add('##14');
sl.Add('##11');
sl.Add('###6');
sl.Add('###5');
sl.Add('##05');
sl.Sort;
ShowMessage(sl.Text);\0
Code: Alles auswählen
05
##05
11
##11
13
##13
14
##14
5
###5
6
###6
Code: Alles auswählen
program Project1;
{$mode objfpc}{$H+}
uses
Classes;
var
sl: TStringList;
i: Integer;
begin
sl := TStringList.Create;
sl.Add('##13');
sl.Add('##14');
sl.Add('##11');
sl.Add('###6');
sl.Add('###5');
sl.Add('##05');
sl.Add(' 13');
sl.Add(' 14');
sl.Add(' 11');
sl.Add(' 6');
sl.Add(' 5');
sl.Add(' 05');
for i:=0 to sl.Count-1 do WriteLn(sl[i]);
WriteLn;
sl.Sort;
for i:=0 to sl.Count-1 do WriteLn(sl[i]);
end.
Code: Alles auswählen
##13
##14
##11
###6
###5
##05
13
14
11
6
5
05
5
6
05
11
13
14
###5
###6
##05
##11
##13
##14
Ich habe es nochmals probiert, aber diesmal mit Wine und FPC 3.0.2, da bekomme ich das gleiche Ergebniss wie du.Keine Ahnung, was du da machst, aber Windows und Mint 18.1 sortieren in diesem Programm wie erwartet:
Code: Alles auswählen
function AnsiCompareStr(const S1, S2: string): integer;{$ifdef SYSUTILSINLINE}inline;{$endif}
begin
result:=widestringmanager.CompareStrAnsiStringProc(s1,s2);
end;
function AnsiCompareText(const S1, S2: string): integer;{$ifdef SYSUTILSINLINE}inline;{$endif}
begin
result:=widestringmanager.CompareTextAnsiStringProc(s1,s2);
end;
Code: Alles auswählen
function AnsiCompareStr(const S1, S2: string): integer;{$ifdef SYSUTILSINLINE}inline;{$endif}
begin
// CAPSIZEINT is no-op if Sizeof(Sizeint)<=SizeOF(Integer)
result:=CAPSIZEINT(widestringmanager.CompareStrAnsiStringProc(s1,s2));
end;
function AnsiCompareText(const S1, S2: string): integer;{$ifdef SYSUTILSINLINE}inline;{$endif}
begin
// CAPSIZEINT is no-op if Sizeof(Sizeint)<=SizeOF(Integer)
result:=CAPSIZEINT(widestringmanager.CompareTextAnsiStringProc(s1,s2));
end; \0
Im Anhang mein Code.poste das zugehörige Programm.
Nützt dir dies etwas ?Nenne bitte genau die Bedingungen, unter denen du die falsche Sortierung erhältst,
Code: Alles auswählen
$ fpc -v
Free Pascal Compiler version 3.1.1 [2017/06/16] for x86_64
Copyright (c) 1993-2017 by Florian Klaempfl and others
Fatal: No source file name in command line
Fatal: Compilation aborted
Error: /usr/bin/ppcx64 returned an error exitcode
Code: Alles auswählen
unit LazUTF8;
...
uses
{$ifdef unix}
// WideCompare* functions on Unix requires this. Must be used although it pulls in clib.
cwstring,
{$endif}
...
Aber wehe es befindet sich Buchstaben in der StringList, dann knallt es.Die saubere Lösung wäre eine eigene Vergleichsroutine für CustomSort
Dies habe ich jetzt auch probiert, in der Console ist es anders, irgendwie doof.ch sehe jetzt auch die seltsame Sortierung unter Mint (fpc 3.02). "Schuld" ist die in deinem Projekt über LCL eingebundene Unit LazUF8, die cwstring verwendet (In meiner Konsolen-Version war diese nicht eingebunden):
Natürlich. Wenn Buchstaben drinnen sind, dann hoffe ich, dass der Programmierer das weiß und sie herausfiltern kann. Aber man sollte ehrlichgesagt auch Zahlen nicht als Strings speichern. Aber das ist nun mal das Thema dieses Threads.Mathias hat geschrieben:Aber wehe es befindet sich Buchstaben in der StringList, dann knallt es.
Das kommt mehr von als man denkt, ein Beispiel, CD-Titel.Aber man sollte ehrlichgesagt auch Zahlen nicht als Strings speichern. Aber das ist nun mal das Thema dieses Threads.
Code: Alles auswählen
01 - Erstes Lied
02 - zweites Lied
03 - etc.