Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Invertieren eines Unicodestrings mit Sonderzeichen (https://www.delphipraxis.net/196764-invertieren-eines-unicodestrings-mit-sonderzeichen.html)

Harry Stahl 17. Jun 2018 22:13

Invertieren eines Unicodestrings mit Sonderzeichen
 
Liste der Anhänge anzeigen (Anzahl: 1)
Wenn ich auf einen Text, der als erstes Zeichen das Zeichen 55357 enthält (siehe Screenshot), folgenden Codeschnipsel anwende, um den String einfach nur zu invertieren, dann wird das Sonderzeichen gekillt. Wie muss ich das richtig machen, um auch das Sonderzeichen zu behalten?

Delphi-Quellcode:
procedure TForm15.bnInvertClick(Sender: TObject);
var
  L, Len: Integer; N, S: string;
begin
  Len := Length (edIn.Text);
  S := edIn.Text;

  for L := Len downto 1 do begin
    N := N + S[L];
  end;

  edout.Text := N;
end;
In der DFM-Datei ist der Edit.Text übrigens so abgelegt:

Delphi-Quellcode:
Text =
      #55357#56555' Gute Nachricht '#8211' gro'#223'er Sommerspa'#223' zu kleinen Preisen bei eBa' +
      'y'
Das Sonderzeichen dürfte also in Wahrheit aus 2 16-bit Werten bestehen, so dass die Umkehrung der Reihenfolge beiden Werte das Zeichen kaputt macht?

Uwe Raabe 17. Jun 2018 22:30

AW: Invertieren eines Unicodestrings mit Sonderzeichen
 
In System.Character gibt es TCharHelper, der eine Function IsSurrogatePair mitbringt. Damit kannst du diese Sonderzeichen erkennen und entsprechend behandeln.

Harry Stahl 17. Jun 2018 23:06

AW: Invertieren eines Unicodestrings mit Sonderzeichen
 
Liste der Anhänge anzeigen (Anzahl: 1)
Schon mal ein schnelles Danke, Uwe. Hatte da auch dunkel was in Erinnerung, aber leider fiel mir nichts konkretes ein...

So funktioniert es nun:

Delphi-Quellcode:
procedure TForm15.bnInvertClick(Sender: TObject);
var
  L, Len, i, c: Integer; N, S: string;
begin
  S := edIn.Text;
  c := Length (edIn.Text);

  while c >= 1 do begin
    if (c>1) and (S[c].IsSurrogate) and (S[c-1].IsSurrogate) then begin
      if s[c].IsSurrogatePair (S[c-1], S[c]) then begin
        N := N + S[c-1] + S[c];
        dec (c, 2);
      end;
    end else begin
      N := N + S[c];
      dec (c);
    end;
  end;

  edout.Text := N;
end;
Die Problemstellung war nur ein (reduzierter) Ausschnitt aus einer Verschlüsselungsroutine, die ich noch unter Delphi-2007, also NON-Unicode verwendet habe, die Anpassung mit den zusätzlichen Überprüfungen wird wahrscheinlich einiges an Laufzeit kosten, bin mal gespannt..


Alle Zeitangaben in WEZ +1. Es ist jetzt 15:13 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz