Entwickler-Ecke

Grafische Benutzeroberflächen (VCL & FireMonkey) - TStringList und ß / ss


AScomp - Do 27.10.11 02:24
Titel: TStringList und ß / ss
Hallo zusammen,

habe momentan folgendes Problem: Eine sortierte TStringList meint, 'tesst' und 'teßt' seien dasselbe. Darum wird einerseits beim Hinzufügen einer der beiden Werte ignoriert (da dupIgnore), andererseits mit IndexOf der jeweils andere Wert gefunden:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
var
   bla: tstringlist;
begin
     bla := tstringlist.Create;
     bla.Sorted := true;
     bla.Duplicates := dupIgnore;
     bla.Add('tesst');
     showmessage(inttostr(bla.IndexOf('teßt')));
     bla.Free;


Es wird 0 zurückgegeben statt -1.

Habe zwar schon Behelfslösungen gefunden (wie z.B. das Ersetzen von 'ß' durch einen temporären Wert), aber eine wirklich saubere Lösung habe ich bisher nicht gefunden.

Gibt es vielleicht eine StringList, die das korrekt löst (= nur tatsächlich identische Strings werden auch als identisch erkannt, unabhängig von irgendwelchen LocaleSettings)? Oder kann ich die classes.pas so anpassen, dass ss und ß nicht mehr als identisch angesehen werden (wäre mir insofern fast lieber, da ich diese Änderung sonst in mehreren Projekten vornehmen müsste)?

Danke und Gruß

Andy

P.S. Sorry, bin im falschen Forenbereich gelandet, sollte eigentlich in den WinAPI-Bereich.
Moderiert von user profile iconNarses: Das ist hier schon richtig, ist ja eine Onboard-Compo. ;)


Tankard - Do 27.10.11 05:59

Welche Delphi Version hast du denn? Unter Lazarus kommt -1, so wie erwartet.


Nersgatt - Do 27.10.11 06:17

TStrings verwendet da AnsiCompareStr. Das ist der Grund. Ließe sich so lösen:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
  TMyStringList = class(TStringList)
  protected
    function CompareStrings(const S1, S2: string): Integer; override;
  end;

implementation

{ TMyStringList }

function TMyStringList.CompareStrings(const S1, S2: string): Integer;
begin
  Result := CompareStr(S1, S2);
end;


Dann natürlich TMyStringList verwenden:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
procedure TForm10.FormCreate(Sender: TObject);
var
   bla: TMyStringList;
begin
     bla := TMyStringList.Create;
     bla.Sorted := true;
     bla.Duplicates := dupIgnore;
     bla.Add('tesst');
     showmessage(inttostr(bla.IndexOf('teßt')));
     bla.Free;
end;


Ressourcenschutzblöcke nicht vergessen.


AScomp - Do 27.10.11 12:32

Danke Jens, das war's!

Allerdings frage ich mich, warum da offensichtlich vergessen wurde, auf CompareStr bzw. CompareText abzuändern (in classes.pas). Hätten nicht alle Ansi-Funktionen in ihre Unicode-Versionen abgeändert werden sollen?

Btw: Nutze Delphi XE.


Narses - Do 27.10.11 13:32

Moin!

user profile iconAScomp hat folgendes geschrieben Zum zitierten Posting springen:
Allerdings frage ich mich, warum da offensichtlich vergessen wurde, auf CompareStr bzw. CompareText abzuändern (in classes.pas). Hätten nicht alle Ansi-Funktionen in ihre Unicode-Versionen abgeändert werden sollen?
Tja, da ist einfach beim Hersteller nicht mehr die gleiche Qualität vorhanden, wie bei der Umstellung für den generischen String-Typ von ShortString auf AnsiString... :nixweiss: Ist nicht der einzige Bug in dieser Richtung... :roll:

user profile iconAScomp hat folgendes geschrieben Zum zitierten Posting springen:
Btw: Nutze Delphi XE.
Dass es da allerdings auch immer noch nicht korrigiert ist, grenzt schon an Peinlichkeit... :autsch:

Hat einer XE2 mit Quelltext und kann mal grad nachschauen? :lupe:

cu
Narses


AScomp - Do 27.10.11 14:15

Hallo Narses,

habe leider nur die Trial von XE2 und diese nicht mal mehr installiert - sonst hätte man ja einfach meinen Beispiel-Quellcode dort testen können.

Ich verwende jetzt einfach eine eigene Version der classes.pas (abgelegt im Projektverzeichnis, damit die Änderungen bei einem Delphi-Update nicht überschrieben werden).

Gruß

Andy

EDIT: Und Embarcadero habe ich auch informiert, damit vielleicht (ein paar Jahre später) doch noch eine vollständige Unicode-Version kommt. ;)