Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Die Delphi-IDE (https://www.delphipraxis.net/62-die-delphi-ide/)
-   -   Fehler in Case-Konstrukt - E2030 Doppelte Case-Label (https://www.delphipraxis.net/201896-fehler-case-konstrukt-e2030-doppelte-case-label.html)

hschmid67 8. Sep 2019 07:57

Fehler in Case-Konstrukt - E2030 Doppelte Case-Label
 
Hallo Zusammen,

heute habe ich einen seltsamen Fehler, der zunächst in Tokyo aufgetaucht ist und den ich jetzt gerade auch in Rio 10.3.2 getestet habe. Ich möchte einzelne Zeichen konvertieren und hab dazu (vereinfacht zum Vorführen) etwa folgende Prozedur:

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
  i: Integer;
  lStr: string;
begin
  lStr := '123456789';
  for i := 1 to lStr.Length do
  begin
    case lStr[i] of
        #0 .. #44 : ;
       #45         : ;
       #46 .. #47 : ;
       #48 .. #57 : ;
       #58 .. #64 : ;
       #65 .. #90 : ;
       #91 .. #96 : ;
       #97 .. #122 : ;
      #123 .. #137 : ;
      #138         : ; // Hier der Fehler
    end;
  end;
end;
Dabei bekomme ich in der markierten Zeile den folgenden Fehler

Code:
E2030 Doppeltes Case-Label
Wenn ich gleich die Range #123 .. #138 setze, funktioniert das Ganze. Ich verstehe es nicht :( Ist das etwa ein Compiler-Fehler in Delphi? Oder kann mir jemand erklären, was ich hier falsch mache?

Viele Grüße
Harald

Redeemer 8. Sep 2019 08:42

AW: Fehler in Case-Konstrukt - E2030 Doppelte Case-Label
 
Drei Probleme hier: 1. Dein Selektor hat einen anderen Typ als deine Labels. Irgendwas wird hier also implizit gecastet. Dürfte der Compiler auch anmerken. Spoiler: Wie man gleich sieht, werden deine AnsiChar-Labels implizit auf den WideChar-Typ des Selektors gecastet.
2. Zeichenkonstanten sind nicht so, wie man sich das vorstellt. Der Compiler castet nun also deine CP1252-Codepoints in den Labels auf UTF-16-Codepoints, um sie mit dem UTF-16-Codepoint im Selektor zu vergleichen. Das sieht dann so aus:
Delphi-Quellcode:
  for i := 1 to lStr.Length do
  begin
    case Ord(lStr[i]) of
        0 .. 44 : ;
       45 : ;
       46 .. 47 : ;
       48 .. 57 : ;
       58 .. 64 : ;
       65 .. 90 : ;
       91 .. 96 : ;
       97 .. 122 : ;
      123 .. 8240 : ;
      352 : ; // Hier der Fehler, 352 ist ja bereits in 123..8240 abgedeckt
    end;
  end;
Würden wir bis #138 zählen (statt #137) sieht es anders aus:
Delphi-Quellcode:
  for i := 1 to lStr.Length do
  begin
    case Ord(lStr[i]) of
        0 .. 44 : ;
       45 : ;
       46 .. 47 : ;
       48 .. 57 : ;
       58 .. 64 : ;
       65 .. 90 : ;
       91 .. 96 : ;
       97 .. 122 : ;
      123 .. 352: ; // Hier KEIN Fehler
    end;
  end;
3. #129 und vier weitere können nicht auf WideChar gecastet werden.
Also bitte in Case-Anweisungen keine Äpfel mit Birnen vergleichen und überhaupt Strings nicht als Ersatz für Delphi-Referenz durchsuchenTBytes verwenden. Wenn's unbedingt sein muss, je nach Situation AnsiString oder RawByteString verwenden.

Uwe Raabe 8. Sep 2019 08:45

AW: Fehler in Case-Konstrukt - E2030 Doppelte Case-Label
 
Schreib mal ein
Delphi-Quellcode:
{$HIGHCHARUNICODE ON}
vor deine case-Anweisung. Näheres dazu kannst du hier nachlesen: HIGHCHARUNICODE-Direktive

hschmid67 8. Sep 2019 09:06

AW: Fehler in Case-Konstrukt - E2030 Doppelte Case-Label
 
Vielen Dank für Eure Hilfe und die Erklärungen!
Die Zeichensätze und all das Konvertieren bringen mich immer wieder zum Stolpern. Ich werde mir mit Euren Hinweisen noch einiges durchlesen und hoffe, dass ich es endlich besser verstehe ;-)

Viele Grüße
Harald


Alle Zeitangaben in WEZ +1. Es ist jetzt 04:58 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