Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi Strings und Case of (https://www.delphipraxis.net/79536-strings-und-case.html)

Klaus Kirchhoff 24. Okt 2006 13:15


Strings und Case of
 
Ich möchte folgendes realisieren:

Ich habe eine Varable von Type String "xTier" und möchte
mit einer Case-Abfrage eine Auswertung durchführen:

case "xTier" of
Hund : ;
Pferd : ;
katze : ;
end;

Das ist doch möglich oder?

hoika 24. Okt 2006 13:21

Re: Strings und Case of
 
Nein,

du musst if's verwenden.


Heiko

xaromz 24. Okt 2006 13:21

Re: Strings und Case of
 
Hallo,
Zitat:

Zitat von Klaus Kirchhoff
Das ist doch möglich oder?

Nein, das ist nicht ohne Weiteres möglich. Es gibt aber eine Funktion, die Dir den Index eines String-Arrays zurückliefert, damit kannst Du dann Dein case bauen. Leider ist mir gerade der Name entfallen.

//Edit: Name gefunden: Delphi-Referenz durchsuchenAnsiIndexStr. Benötigt die Unit StrUtils.

Gruß
xaromz

GimbaR 24. Okt 2006 13:22

Re: Strings und Case of
 
guggst du hier :???:

Namenloser 24. Okt 2006 13:23

Re: Strings und Case of
 
Weiß eigentlich jemand, warum das so ist? :gruebel:

Klaus01 24. Okt 2006 13:26

Re: Strings und Case of
 
Weil String kein Ordinaltyp ist,
hat also nicht einen eindeutigen Vorgänger oder Nachfolger.

Aber es wurde ja schon geschrieben, wie man das Problem umschiffen kann.

Grüße
Klaus

semo 24. Okt 2006 13:30

Re: Strings und Case of
 
erst gestern hatten wir ein thema dazu :-)
guckst du hier

hanspeter 24. Okt 2006 13:38

Re: Strings und Case of
 
Zitat:

Zitat von NamenLozer
Weiß eigentlich jemand, warum das so ist? :gruebel:

Weil Delphisyntax etwas angestaubt und in die Jahre gekommen ist.
Modernere Compiler wie z.B. Chrome können das.

Gruß Peter

Namenloser 24. Okt 2006 13:39

Re: Strings und Case of
 
Zitat:

Zitat von Klaus01
Weil String kein Ordinaltyp ist,
hat also nicht einen eindeutigen Vorgänger oder Nachfolger.

Aber es wurde ja schon geschrieben, wie man das Problem umschiffen kann.

Grüße
Klaus

Aber warum funktioniert Case denn nur mit Ordinaltypen?
WIE funktioniert case eigentlich?
Ich hätte eigentlich vermutet, dass delphi ein
Delphi-Quellcode:
Case i of
0: bla;
1: blupp;
2: Quak;
end;
wie ein
Delphi-Quellcode:
if i=0 then bla
else if i=1 then blupp
else if i=2 then Quak;
interpretiert...

Edit: Hätte da nicht ein roter kasten sein müssen o.ô

Reinhard Kern 24. Okt 2006 14:11

Re: Strings und Case of
 
Zitat:

Zitat von NamenLozer

Aber warum funktioniert Case denn nur mit Ordinaltypen?
WIE funktioniert case eigentlich?

Hallo,

case verwendet ja nicht nur einen einzigen Fall, sondern eine Liste davon:

Delphi-Quellcode:
case i of
  1..9 : UnterZehn := true;
  end;
daher Ordinalzahl. Eine Angabe wie "alles zwischen Edit1.Text und Edit2.Text" ist einfach undefinierbar.

Gruss Reinhard

Khabarakh 24. Okt 2006 14:22

Re: Strings und Case of
 
Natürlich lassen sich Pascal-Mengen nur mit Ordinaltypen bilden, aber das ist ja keine Erklärung dafür, dass auch einzelne Nihct-Ordinal-Typen nicht funktionieren.
Das eigentliche Problem ist gleichzeitig der Vorteil von Case: es wird eine effiziente Sprungtabelle erstellt. http://www.delphipraxis.net/internal...=187088#187088

Namenloser 24. Okt 2006 14:38

Re: Strings und Case of
 
Danke, genau das wollte ich wissen!

Bernhard Geyer 24. Okt 2006 14:51

Re: Strings und Case of
 
Ist nicht im Gespräch case of für Strings in einer der nächsten Delphi-Versionen zu ergänzen :gruebel:
Irgendwo (Borland-Community, Borland-Blogs, EKON, ...) hab ich das gehört das man hier nicht hinter C# und konsorten hinterherhinken will. Evtl. auch nur für .NET angedacht.

EWeiss 24. Okt 2006 15:40

Re: Strings und Case of
 
Zitat:

Zitat von Klaus Kirchhoff
Ich möchte folgendes realisieren:

Ich habe eine Varable von Type String "xTier" und möchte
mit einer Case-Abfrage eine Auswertung durchführen:

case "xTier" of
Hund : ;
Pferd : ;
katze : ;
end;

Das ist doch möglich oder?

Ja auf umwegen ..
Beispiel: Filetypen
Delphi-Quellcode:
  FileExt : array [0 ..10] of string = ('.mp3','.wav','.wma','.aiff','.aif','.ogg',
                                      '.wmv','.mpeg','.mpg','.dat','.avi');
Delphi-Quellcode:
var
  FileType  : string;
  playindex : integer;
  ArrayIndex : integer;

begin
    PlaylistIndex := Playlist.ItemIndex;
    // Aktiven PlaylistIndex zuweisen
    FileType     := Trim(ExtractFileExt(fFiles[playindex].Dateiname));
    // FileType = Extension ermitteln
    for ArrayIndex := 0 to 10 do
    // Schleife durchlaufen bis übereinstimmendes ArrayIndex gefunden
      if FileExt[ArrayIndex] = FileType then
      // FileType mit FileExt(ArrayIndex) vergleichen
      // und gefundenen ArrayIndex zuweisen
        break;
        // Raus hier wenn gefunden!
    if FileType <> '' then
    // Übereinstimmenden FileType gefunden
    // dann weiter..
    begin
      case ArrayIndex of
        // Audio
        // unten stehenden ArrayIndex gefunden dann DateiTyp = Audio
        0, 1, 2, 3, 4, 5:
        begin
        //....
        end;
        // Video
        // unten stehenden ArrayIndex gefunden dann DateiTyp = Video
        6, 7, 8, 9, 10:
        begin
        // ....
        end;
      end;
    end;
end;
Anstelle der extensions kannst du xbeliebige strings eingeben.

gruß

alzaimar 24. Okt 2006 16:28

Re: Strings und Case of
 
Der Code wird so vollkommen unleserlich. Grundsätzlich ist so eine Vorgehensweise sicherlich ok, aber das muss man -finde ich- etwas genauer bertrachten.

Für Deinen Code ist ein String ein unglaublich umständlich zu behandelndes Ding. Code will einfache Datentypen (Word, Integer, Zeichen, Pointer, Double). Ich würde einen String sofort nachdem er aufgetaucht ist, in eine Zahl umwandeln, oder hier, in eine Aufzählung (enum), also z.B. (natürlich mit einem Array, das dient hier nur zur Anschauung):
Delphi-Quellcode:
Type
  TTier = (trUnbekannt, trHund, trKatze, trPferd);

Function StringToTier (Const aTierName : String) : TTier;
Begin
  If atierName = 'Hund' Then
    Result := trHund
  Else if aTierName ='Katze' Then
    Result := trKatze
  Else if aTierName = 'Pferd' Then
    Result := trPferd
  Else
    Result := trUnbekannt
End;
Nun kannst Du erstmal deinen String in ein (T)Tier verwandeln und dann ordendlich und effizient damit arbeiten. Wenn Du es darstellen (anzeigen) willst, verwendest Du die Umkehrfunktion.
Delphi-Quellcode:
Var
  myTier : TTier;

Begin
  ...
  myTier := StringToTier (Edit1.Text);
  Case myTier Of
    trHund : ...
    trKatze : ...
    trPferd : ...
    trUnbekannt : ...
  End;
So ist das doch viel Übersichtlicher.

Neutral General 24. Okt 2006 16:46

Re: Strings und Case of
 
Oder ne theoretische andere Methode wäre auch

Delphi-Quellcode:
Case Length(String) of
...
end;
Nur müssen die Strings dann auch eindeutig zuortenbar (<-- das is nie im Leben richtig geschrieben aber ich steh auf der Leitung-.-^^) sein ;)

xaromz 24. Okt 2006 19:45

Re: Strings und Case of
 
Hallo,

genau das, was in den Beiträgen #14 und #15 passiert, macht die von mir schon angegebene Funktion AnsiIndexStr.

Gruß
xaromz

alzaimar 24. Okt 2006 19:55

Re: Strings und Case of
 
Völlig richtig. Ich schrieb auch, das das soweit korrkt ist, man sich aber eben noch ein paar Gedanken mehr drüber machen sollte, so von wegen Trennung von Darstellung und Ausführung.

Leider liefert AnsiIndexStr nur eine Zahl, und da steckt keine Semantik hinter. Ich will doch lesbaren Code, der auch später noch verstanden wird. Da hilft mir ein
Delphi-Quellcode:
Case AnsiIndexStr(Edit1.Text, Animals) Of
  0 : ...
  1 : ...
End;
Nix..

Aber verwenden(!) würde ich die Funktion auf alle Fälle...

xaromz 24. Okt 2006 20:14

Re: Strings und Case of
 
Hallo,
Zitat:

Zitat von alzaimar
Leider liefert AnsiIndexStr nur eine Zahl, und da steckt keine Semantik hinter. Ich will doch lesbaren Code, der auch später noch verstanden wird.

Da hast Du natürlich Recht.
Zitat:

Zitat von alzaimar
Aber verwenden(!) würde ich die Funktion auf alle Fälle...

Man kann sich die Semantik natürlich für diesen Fall basteln, indem man Konstanten definiert (HUND = 1; KATZE = 2;...).

Gruß
xaromz

EWeiss 25. Okt 2006 16:29

Re: Strings und Case of
 
Zitat:

Zitat von alzaimar
Der Code wird so vollkommen unleserlich. Grundsätzlich ist so eine Vorgehensweise sicherlich ok, aber das muss man -finde ich- etwas genauer bertrachten.

Für Deinen Code ist ein String ein unglaublich umständlich zu behandelndes Ding. Code will einfache Datentypen (Word, Integer, Zeichen, Pointer, Double). Ich würde einen String sofort nachdem er aufgetaucht ist, in eine Zahl umwandeln, oder hier, in eine Aufzählung (enum), also z.B. (natürlich mit einem Array, das dient hier nur zur Anschauung):
Delphi-Quellcode:
Type
  TTier = (trUnbekannt, trHund, trKatze, trPferd);

Function StringToTier (Const aTierName : String) : TTier;
Begin
  If atierName = 'Hund' Then
    Result := trHund
  Else if aTierName ='Katze' Then
    Result := trKatze
  Else if aTierName = 'Pferd' Then
    Result := trPferd
  Else
    Result := trUnbekannt
End;
Nun kannst Du erstmal deinen String in ein (T)Tier verwandeln und dann ordendlich und effizient damit arbeiten. Wenn Du es darstellen (anzeigen) willst, verwendest Du die Umkehrfunktion.
Delphi-Quellcode:
Var
  myTier : TTier;

Begin
  ...
  myTier := StringToTier (Edit1.Text);
  Case myTier Of
    trHund : ...
    trKatze : ...
    trPferd : ...
    trUnbekannt : ...
  End;
So ist das doch viel Übersichtlicher.

Meiner meinung nach sind IF abfragen als lösung nicht der richtige weg..
Stell dir vor du hast 2000 Tiere die überprüft werden müssen, dein Tier ist das 2000
dann muss jede IF abfrage überprüft werden bis du zum ziel kommst.

Das geht mit einer For und Case Anweisung allemal schneller.

gruß

alzaimar 25. Okt 2006 16:41

Re: Strings und Case of
 
Zitat:

Zitat von EWeiss
Meiner meinung nach sind IF abfragen als lösung nicht der richtige weg..

Zitat:

Zitat von alzaimar
.... Ich würde einen String sofort nachdem er aufgetaucht ist, in eine Zahl umwandeln, oder hier, in eine Aufzählung (enum), also z.B. (natürlich mit einem Array, das dient hier nur zur Anschauung):

Immer Alles lesen :mrgreen:

EWeiss 25. Okt 2006 16:51

Re: Strings und Case of
 
Zitat:

Immer Alles lesen
Jawohl Chef habs gelesen :duck: :mrgreen:

gruß

Hansa 25. Okt 2006 16:53

Re: Strings und Case of
 
Zitat:

Zitat von EWeiss
Meiner meinung nach sind IF abfragen als lösung nicht der richtige weg..
Stell dir vor du hast 2000 Tiere die überprüft werden müssen, dein Tier ist das 2000
dann muss jede IF abfrage überprüft werden bis du zum ziel kommst...

Deshalb sucht man ja nicht nach einem String ! Man benutzt einen Ordinaltyp, der eben nicht beeinflusst wird von Groß/Kleinschreibung usw. Und die werden eben durchnummeriert (mit IDs etc.). Wer soll denn mit einem 2000-Zeilen Case was anfangen ? Das macht nur Sinn bei Fehlermeldungen, also in Ausnahmefällen.

BigBob 2. Mär 2007 17:32

Re: Strings und Case of
 
Hi Leute!

Bin neu auf dem Board ... naja, ich hol dieses Thema nochmal ans Tageslicht.
Die Idee mit Strings in Integer umzuwandeln ist schön und gut, aber genau das will ich umsetzen. Die Sache ist die: ich habe 32 feste Strings die der Bediener eingeben können muss (später vllt noch ein paar mehr), und die will ich ja gerade in Zahlen umwandeln. Aber da hilft mir "case ... of" nicht weiter. Wie würdet ihr so ein Problem lösen? Mit "if ... then ... else" ist es nur noch mehr schreibarbeit als es mit "case ... of" ohnehin schon ist. Ich hoffe ihr habt da noch einen Vorschlag.


MfG BigBob
PS: ich bin ganz neu in der Materie und versuche mit meinem begrenzten Wissen ein Skat-Computer zu proggen ... das erweist sich aber bisher als heikles unterfangen, dabei bin ich immernoch beim kartengeben und -lesen *grml*

DGL-luke 2. Mär 2007 17:53

Re: Strings und Case of
 
Hallo,

Delphi-Quellcode:
case StrUtils.AnsiIndexStr(['foo','bar']) of
  0:;
  1:;
end;
so was?

BigBob 2. Mär 2007 19:54

Re: Strings und Case of
 
Zitat:

Zitat von DGL-luke
Hallo,

Delphi-Quellcode:
case StrUtils.AnsiIndexStr(['foo','bar']) of
  0:;
  1:;
end;
so was?


Hmmm ... daraus werd ich nicht schlau, da muss ich mir nochmal die Tipps hier Thread angucken.
Ursprünglich sah das bei mir so aus:

Delphi-Quellcode:
case befehl of 'Karo 7'      : gesetzt:=1;
                 'Karo 8'         : gesetzt:=2;
                 'Karo 9'         : gesetzt:=3;
                 'Karo Bube'   : gesetzt:=4;
                 'Karo Dame'   : gesetzt:=5;
                 'Karo König'     : gesetzt:=6;
                 'Karo 10'     : gesetzt:=7;
                 'Karo Ass'       : gesetzt:=8;
                 'Herz 7'         : gesetzt:=9;
                 'Herz 8'         : gesetzt:=10;
                 'Herz 9'         : gesetzt:=11;
                 'Herz Bube'     : gesetzt:=12;
                 'Herz Dame'     : gesetzt:=13;
                 'Herz König'     : gesetzt:=14;
                 'Herz 10'       : gesetzt:=15;
                 'Herz Ass'       : gesetzt:=16;
                 'Pik 7'         : gesetzt:=17;
                 'Pik 8'         : gesetzt:=18;
                 'Pik 9'         : gesetzt:=19;
                 'Pik Bube'       : gesetzt:=20;
                 'Pik Dame'       : gesetzt:=21;
                 'Pik König'     : gesetzt:=22;
                 'Pik 10'         : gesetzt:=23;
                 'Pik Ass'       : gesetzt:=24;
                 'Kreuz 7'       : gesetzt:=25;
                 'Kreuz 8'       : gesetzt:=26;
                 'Kreuz 9'       : gesetzt:=27;
                 'Kreuz Bube'     : gesetzt:=28;
                 'Kreuz Dame'     : gesetzt:=29;
                 'Kreuz König'   : gesetzt:=30;
                 'Kreuz 10'       : gesetzt:=31;
                 'Kreuz Ass'     : gesetzt:=32
                 ELSE gesetzt:=0 END;
Aber ich habs jetz umgeändert mit der "if" Anweisung. Ich nehme den Frage-Button wieder raus, aber trotzdem: muss das sein?:

Delphi-Quellcode:
if befehl='Karo 7' then gesetzta:=1 else        {Kartenwert nach Kartenname ermitteln}
  if befehl='Karo 8' then gesetzta:=2 else
  if befehl='Karo 9' then gesetzta:=3 else
  if befehl='Karo Bube' then gesetzta:=4 else
  if befehl='Karo Dame' then gesetzta:=5 else
  if befehl='Karo König' then gesetzta:=6 else
  if befehl='Karo 10' then gesetzta:=7 else
  if befehl='Karo Ass' then gesetzta:=8 else
  if befehl='Herz 7' then gesetzta:=9 else
  if befehl='Herz 8' then gesetzta:=10 else
  if befehl='Herz 9' then gesetzta:=11 else
  if befehl='Herz Bube'   then gesetzta:=12 else
  if befehl='Herz Dame'   then gesetzta:=13 else
  if befehl='Herz König' then gesetzta:=14 else
  if befehl='Herz 10'   then gesetzta:=15 else
  if befehl='Herz Ass' then gesetzta:=16 else
  if befehl='Pik 7'   then gesetzta:=17 else
  if befehl='Pik 8'   then gesetzta:=18 else
  if befehl='Pik 9'   then gesetzta:=19 else
  if befehl='Pik Bube' then gesetzta:=20 else
  if befehl='Pik Dame' then gesetzta:=21 else
  if befehl='Pik König'   then gesetzta:=22 else
  if befehl='Pik 10' then gesetzta:=23 else
  if befehl='Pik Ass'   then gesetzta:=24 else
  if befehl='Kreuz 7'   then gesetzta:=25 else
  if befehl='Kreuz 8'   then gesetzta:=26 else
  if befehl='Kreuz 9'   then gesetzta:=27 else
  if befehl='Kreuz Bube' then gesetzta:=28 else
  if befehl='Kreuz Dame' then gesetzta:=29 else
  if befehl='Kreuz König'   then gesetzta:=30 else
  if befehl='Kreuz 10' then gesetzta:=31 else
  if befehl='Kreuz Ass'   then gesetzta:=32 else gesetzta:=0;

Wie unschwer auffällt ist das eine Menge Schreibkram. Naja, wenn jemand ne Idee hat, wie es hätte schneller gehen können, bin ich dafür offen. Ansonsten is meine Frage beantwortet.


MfG BigBob

DGL-luke 2. Mär 2007 22:06

Re: Strings und Case of
 
Das is ja bei dir noch viel einfacher...

Delphi-Quellcode:
gesetzt := AnsiIndexStr(['Karo 7'],['Karo 8']{,...})+1;
if gesetzt = -1 then
  gesetzt := 0;

Hobby-Programmierer 2. Mär 2007 22:37

Re: Strings und Case of
 
Nabend ...,
mir fallen spontan 2 mögliche Lösungen ein.
Array definieren
Delphi-Quellcode:
const Karte_Name: Array[1..32] of String = ('Karo 7','Karo 8','Karo 9',
                                            'Karo Bube','Karo Dame','Karo König',
                                            'Karo 10','Karo Ass',
                                            'Herz 7','Herz 8','Herz 9',
                                            'Herz Bube','Herz Dame','Herz König',
                                            'Herz 10','Herz Ass',
                                            'Pik 7','Pik 8','Pik 9',
                                            'Pik Bube','Pik Dame','Pik König',
                                            'Pik 10','Pik Ass',
                                            'Kreuz 7','Kreuz 8','Kreuz 9',
                                            'Kreuz Bube','Kreuz Dame','Kreuz König',
                                            'Kreuz 10','Kreuz Ass');
und dann die Abfragen
Delphi-Quellcode:
procedure TForm1.ButtonClick(Sender: TObject);
var i: integer;
    Karte: String;
begin
  Karte:= 'Karo 10';
  for i:= 1 to High(Karte_Name) do
    if Karte_Name[i] = Karte then
      showmessage(Karte+ ' mit Wert '+ IntToStr(i)+ ' gesetzt');
end;

procedure TForm1.ButtonClick(Sender: TObject);
var i: integer;
    Karte: String;
begin
  Karte:= 'Karo 10';
  i:= AnsiIndexStr(Karte, Karte_Name) +1;
  showmessage(Karte+ ' mit Wert '+ IntToStr(i)+ ' gesetzt);
end;
LG Mario


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