Delphi-PRAXiS
Seite 1 von 3  1 23      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Elemente aus TStringList in Laufzeit entfernen (https://www.delphipraxis.net/198592-elemente-aus-tstringlist-laufzeit-entfernen.html)

KetchUp 16. Nov 2018 16:21

Elemente aus TStringList in Laufzeit entfernen
 
Hallo, ich will als Schulprojekt einen Vokabeltrainer erstellen der Vokabeln aus einer TXT Datei liest und den Benutzer diese abfragt. Dabei sollen die Vokabeln sooft zufällig abgefragt werden bis man sie 3 mal hintereinander richtig eingegeben hat.

Funktioniert soweit auch, nur wenn ich eine Vokabel aus der TStringList entferne, gibt es einen "List index out of bounds" Error. Vermutlich löscht Delphi die Vokabel, nur ohne die verbleibenden neu zu sortieren und somit erwischt der Zufallsgenerator mal einen Wert, der im Index nicht mehr vorhanden ist.

Wie kann ich das Problem beheben?

Code:
    Begin
      Input:= E_UserGuess.Text;                                        
      E_UserGuess.Text:= '';                                          


      Answer:=AnsiCompareStr(VocabularyEnglish[RandomNumber], Input);  

      If Answer=0
        Then
          Begin
            L_CorrectAnswer.Caption:='';
            jpg:= TJpegImage.Create;
            jpg.LoadFromFile('True.jpg');
            Img_FeedBack.Picture.Bitmap.Assign(jpg);
            jpg.free;
          End

        Else
          Begin
            L_CorrectAnswer.Caption:='Deine Antwort: '+(Input)+'     '+'Richtige Antwort: '+(VocabularyEnglish[RandomNumber]);
            jpg:= TJpegImage.Create;
            jpg.LoadFromFile('False.jpg');
            Img_FeedBack.Picture.Bitmap.Assign(jpg);
            jpg.free;
          End;


          RepetitionCheck:=RandomNumber;                                          
          While RepetitionCheck = RandomNumber Do RandomNumber:=random(WordCount);

        VocabularyEnglish:= TStringList.Create;                
        VocabularyGerman:= TStringList.Create;                  

          try

            VocabularyEnglish.LoadFromFile('Vocabulary.txt');      
            VocabularyGerman.LoadFromFile('Vocabulary2.txt');        
            VocabularyGerman.Delete(RandomNumber);
            VocabularyEnglish.Delete(RandomNumber);
            L_RemainingWords.Caption:= 'Verbleibende Vokabeln: '+IntToStr(VocabularyGerman.Count);
            L_RemainingWords.Font.Name:='Helvetica LT Std';
            L_RemainingWords.Font.Size:= 16;
            L_RemainingWords.Font.Color:= RGB(170,220,70);

            finally
            VocabularyGerman.Free;
          end;
PS: Die deutschen und englischen Vokabeln liegen in 2 separaten Textdateien, da ich es noch nicht geschafft haben die Wörter aus einer Datei getrennt auszulesen.

Dalai 16. Nov 2018 16:44

AW: Elemente aus TStringList in Laufzeit entfernen
 
Stringlisten beginnen bei Index 0. Nicht nur deswegen solltest du sicherstellen, dass deine Variable RandomNumber im Bereich zwischen 0 und TStringList.Count-1 liegt, bevor du sie als Index für die Stringliste(n) benutzt (z.B. zum Löschen eines Strings aus der Liste).

Grüße
Dalai

DieDolly 16. Nov 2018 16:52

AW: Elemente aus TStringList in Laufzeit entfernen
 
Zitat:

PS: Die deutschen und englischen Vokabeln liegen in 2 separaten Textdateien, da ich es noch nicht geschafft haben die Wörter aus einer Datei getrennt auszulesen.
Ich denke hier gerade spontan an eine Liste, wo DE und EN per Kommata getrennt stehen
Code:
Haus,House
Hund,Dog
Code:
var
 Vocab: TStringDynArray;
begin
 Vocab := liste.strings[i].Split([',']);
 // DE: Vocab[0]
 // EN: Vocab[1]
ungetestet

DP-Maintenance 16. Nov 2018 16:58

Dieses Thema wurde am "16. Nov 2018, 17:58 Uhr" von "Luckie" aus dem Forum "Algorithmen, Datenstrukturen und Klassendesign" in das Forum "Object-Pascal / Delphi-Language" verschoben.

KetchUp 16. Nov 2018 17:11

AW: Elemente aus TStringList in Laufzeit entfernen
 
Zitat:

Zitat von Dalai (Beitrag 1418253)
Stringlisten beginnen bei Index 0. Nicht nur deswegen solltest du sicherstellen, dass deine Variable RandomNumber im Bereich zwischen 0 und TStringList.Count-1 liegt, bevor du sie als Index für die Stringliste(n) benutzt

Danke, ich wusste das die Liste mit 0 beginnt aber das mit dem Count-1 muss ich mir noch mal anschauen.

Danke für den Tipp @DieDolly, probier ich gleich mal aus. :thumb:

DieDolly 16. Nov 2018 17:13

AW: Elemente aus TStringList in Laufzeit entfernen
 
Zitat:

Danke, ich wusste das die Liste mit 0 beginnt aber das mit dem Count-1 muss ich mir noch mal anschauen.
Beispieliste
Zitat:

A
B
C
D
Code:
[0] => A

Count-1 => D
Count ergebe hier 4. Um auf das vierte Item zuzugreifen, muss man aber [3] nutzen (weil die Liste null-basiert ist, erstes Item 0, zweites 1 usw.).

Tipp am Rande: wenn dein Lehrer anfängt Arrays zu deklarieren wie test: array[1 .. 19] dann ignorier das am besten. Diese verfluchten 1-basierten Deklarationen erzeugen nur Probleme früher oder später.

Delphi.Narium 16. Nov 2018 17:54

AW: Elemente aus TStringList in Laufzeit entfernen
 
'ne Stringliste ist eigentlich schon geeignet.

Wenn man eine Datei hat, in der die Vokabeln in dieser Form stehen:
Code:
englisch=deutsch
House=Haus
Car=Auto
so kann man mit
Delphi-Quellcode:
EnglischeVokabel := VokabelStringliste.Names[RandomNumer];
DeutschVokabel := VokabelStringliste.ValueFromIndex(RandomNumber);
den Inhalt abfragen, ohne dass man dabei dann zwei Dateien parallel pflegen muss.

Die Pflege kann man im Programm recht leicht mit 'nem TValueListEditor realisieren. Der dürfte irgendwo in der Komponentenpalette zu finden sein.

KetchUp 16. Nov 2018 18:13

AW: Elemente aus TStringList in Laufzeit entfernen
 
Zitat:

Zitat von DieDolly (Beitrag 1418258)
Count ergebe hier 4. Um auf das vierte Item zuzugreifen, muss man aber [3] nutzen (weil die Liste null-basiert ist, erstes Item 0, zweites 1 usw.).

Danke, jetzt hab ich das auch verstanden :-D

Zitat:

Zitat von Delphi.Narium (Beitrag 1418260)
so kann man mit
Delphi-Quellcode:
EnglischeVokabel := VokabelStringliste.Names[RandomNumer];
DeutschVokabel := VokabelStringliste.ValueFromIndex(RandomNumber);

Danke das funktinoniert super. Aber warum weiß Delphi bei ".Names" das ich den Text vor dem "=" haben will und bei ".ValueFromIndex" den Text dahinter?

DieDolly 16. Nov 2018 18:21

AW: Elemente aus TStringList in Laufzeit entfernen
 
Zitat:

Aber warum weiß Delphi bei ".Names" das ich den Text vor dem "=" haben will und bei ".ValueFromIndex" den Text dahinter?
Das sagen doch schon die Zugriffe. Mit Names greift man auf den Namen zu (das vor dem =) und Value ist das nach dem =.

Delphi.Narium 16. Nov 2018 18:51

AW: Elemente aus TStringList in Laufzeit entfernen
 
Zitat:

Zitat von KetchUp (Beitrag 1418261)
Danke das funktinoniert super. Aber warum weiß Delphi bei ".Names" das ich den Text vor dem "=" haben will und bei ".ValueFromIndex" den Text dahinter?

Das stammt noch aus den Windowsanfangszeiten, als Konfigurationen (fast ausschließlich) in INI-Dateien gespeichert wurden.

INI-Dateien bestehen aus Bereichen und Werteparen:
Code:
[BereichMitBeliebigemEindeutigemNamen]
Name1=Wert1
Name2=Wert2
Name3=Wert3
[EnglischDeutsch]
Car=Auto
House=Haus
Delphi=Delphi
[DeutschEnglisch]
Auto=Car
Haus=House
Delphi=Delphi
[WeiterSprachpaareMoeglich]
...=...
Vor dem Gleichheitszeichen steht der Name (Mehrzahl = Namen -> englisch = Names) des zu konfigurierenden "Teils" und hinter dem Gleichheitszeichen sein Wert (eine mögliche Übersetzung von Wert ins Englische ist Value (Einzahl) -> Values (Mehrzahl)).

Und das ist ein "Wissen", was man Delphi schon von Anfang an beigebracht hat und heute immernoch nutzen kann, um mit wenig Aufwand 'nen Vokabeltrainer zu schreiben ;-)

KetchUp 16. Nov 2018 20:06

AW: Elemente aus TStringList in Laufzeit entfernen
 
Zitat:

Zitat von Delphi.Narium (Beitrag 1418267)
Das stammt noch aus den Windowsanfangszeiten, als Konfigurationen (fast ausschließlich) in INI-Dateien gespeichert wurden.

Vor dem Gleichheitszeichen steht der Name (Mehrzahl = Namen -> englisch = Names) des zu konfigurierenden "Teils" und hinter dem Gleichheitszeichen sein Wert (eine mögliche Übersetzung von Wert ins Englische ist Value (Einzahl) -> Values (Mehrzahl)).

Vielen Dank! Das war genau die Hintergrundinformation die ich wissen wollte. :thumb:

KetchUp 17. Nov 2018 13:01

AW: Elemente aus TStringList in Laufzeit entfernen
 
So ganz scheint es doch nicht mit "Names" und "ValueFromIndex" zu funktionieren. Ich hab jetzt alles darauf umgeschrieben, bekomme auch keinen Compiler Error aber wieder ein "List Index out of Bounds" Fehler. Der tritt genau in der Zeile auf wo die Eingabe der Vokabel mit der in der TXT-Datei hinterlegten verglichen wird.

Code:
 Begin
      Input:= E_UserGuess.Text;
      E_UserGuess.Text:= '';

      Answer:=AnsiCompareStr(Vocabulary.Names[RandomNumber], Input);

          RepetitionCheck:=RandomNumber;                                          
          While RepetitionCheck = RandomNumber Do RandomNumber:=random(WordCount);

          try
            Vocabulary:= TStringList.Create;                                
            Vocabulary.LoadFromFile('Vocabulary.txt');                    
            L_UnknownWord.Caption:= Vocabulary.ValueFromIndex[RandomNumber];    
            finally
            Vocabulary.Free;
          end;

    end
Wenn ich "Answer:=AnsiCompareStr(Vocabulary.Names[RandomNumber], Input);" auskommentiere geht es aber ich muss die Wörter vergleichen. Es liegt auch nicht an "RandomNumber", wenn ich das durch eine Zahl ersetze kommt der gleiche Fehler.

Gibt es noch eine Möglichkeit die zu vergleichen?

Delphi.Narium 17. Nov 2018 13:19

AW: Elemente aus TStringList in Laufzeit entfernen
 
Woher kommt WordCount, das darf maximal Vocabulary.Count - 1 sein.

Wenn Du aber erst eine Zufallszahl im Bereich bis WordCount "würfelst", aber WordCount zufällig größer als Vocabulary.Count - 1 ist, kann es sporadisch Fehler geben.

Delphi-Quellcode:
  While RepetitionCheck = RandomNumber Do RandomNumber := Random(Vocabulary.Count - 1);


Achso:

Die Vokabeln für jede einzelne Abfrage neu zu laden, halte ich nicht für so eine besonders gute Idee.

Das sollte einmal (z. B. beim Programmstart) geschehen, ebenso das Freigeben der Vokabelliste.

DieDolly 17. Nov 2018 13:37

AW: Elemente aus TStringList in Laufzeit entfernen
 
Zitat:

So ganz scheint es doch nicht mit "Names" und "ValueFromIndex" zu funktionieren. Ich hab jetzt alles darauf umgeschrieben, bekomme auch keinen Compiler Error aber wieder ein "List Index out of Bounds" Fehler.
Viele Fehler lassen sich schon alleine durch ordentliches Einrücken und respektieren des Delphi Styleguides auffinden.

KetchUp 17. Nov 2018 13:40

AW: Elemente aus TStringList in Laufzeit entfernen
 
Zitat:

Zitat von Delphi.Narium (Beitrag 1418301)
Woher kommt WordCount, das darf maximal Vocabulary.Count - 1 sein.

WordCount wird unter "FormCreate" auf 3 Festgelegt (nur zum testen). Es sind auch genau 3 Vokabeln in der TXT-Datei die im Moment so aussieht:

Code:
black=schwarz
red=rot
blue=blau
In FormCreat steht noch folgendes damit die erste Vokabel sofort bei Programmstart angezeigt wird:

Code:
 WordCount:= 3;
 RandomNumber:= random(WordCount);                  

    try
      Vocabulary:= TStringList.Create;                
      Vocabulary.LoadFromFile('Vocabulary.txt');      

      L_UnknownWord.Caption:= Vocabulary.ValueFromIndex[RandomNumber];
      L_CorrectAnswer.Caption:= '';

      finally
      Vocabulary.Free;
    end

Zitat:

Zitat von Delphi.Narium (Beitrag 1418301)
Wenn Du aber erst eine Zufallszahl im Bereich bis WordCount "würfelst", aber WordCount zufällig größer als Vocabulary.Count - 1 ist, kann es sporadisch Fehler geben.

Der Fehler tritt IMMER auf. Das ist ja das Komische.



Zitat:

Zitat von Delphi.Narium (Beitrag 1418301)
Die Vokabeln für jede einzelne Abfrage neu zu laden, halte ich nicht für so eine besonders gute Idee.

Jap, das hab ich mir auch gedacht, ist aber im Moment die einzige Möglichkeit das Programm zum Laufen zu bekommen :oops:

DieDolly 17. Nov 2018 13:50

AW: Elemente aus TStringList in Laufzeit entfernen
 
gelöscht

KetchUp 17. Nov 2018 14:00

AW: Elemente aus TStringList in Laufzeit entfernen
 
[QUOTE=DieDolly;1418306]
Zitat:

Beispielhaft das Record
Delphi-Quellcode:
TVocab = record
 German, English: string;
end;
Beim Laden des Programms erzeugst du für jede Vokabel ein Record und packst sie alle in eine Liste.
Danke für den Tipp, ich hab zwar keine Ahnung von Records, werde mich aber jetzt mal einlesen. :wink:

DieDolly 17. Nov 2018 14:02

AW: Elemente aus TStringList in Laufzeit entfernen
 
Es wird sich lohnen. Das sage ich immer wieder.
Am besten gleich richtig machen denn sonst wirst du deinen Code später hassen.

Stell dir ein Record vor wie eine Kiste für Schrauben. In der Kiste gibt es Fächer für jede Schraubenart. Deine Kiste heißt TVocab (wovon du eine "Instanz" erstellst die dann in die Liste [die Liste ist dein Schrank wo all die Kisten drin sind] kommt) in deine Kiste kann zwei Arten von Schrauben fassen: Deutsche und Englische. Das sind natürlich Strings.

http://www.delphibasics.co.uk/Article.asp?Name=Records
https://stackoverflow.com/questions/...ist-of-records

KetchUp 17. Nov 2018 14:09

AW: Elemente aus TStringList in Laufzeit entfernen
 
Funktioniert das noch mit der TStringList? Denn ich muss die Vokabeln während der Laufzeit entfernen können und jeder Vokabel eine Variable zuordnen können um zu überprüfen, wie oft sie schon richtig eingegeben wurde.

DieDolly 17. Nov 2018 14:12

AW: Elemente aus TStringList in Laufzeit entfernen
 
gelöscht

DieDolly 17. Nov 2018 14:24

AW: Elemente aus TStringList in Laufzeit entfernen
 
Heute will ich mal nett sein. Hier ein Beispiel mit generischer TList und Klasseninstanzen.
Gelöscht weil der TE sich nur für deine StringListe interessiert

Delphi.Narium 17. Nov 2018 14:39

AW: Elemente aus TStringList in Laufzeit entfernen
 
Stringlisten werden von 0 bis Count - 1 gezählt.

Bei drei Worten in der Stringliste darf WordCount daher nur 2 sein.

Maximalwert für WordCount = Anzahl der Wörter in der Liste - 1;

WordCount solltest Du nach dem Laden der Stringliste auf Stringliste.Count - 1 setzen und nicht irgendwo am Programmstart auf den vermutet richtigen Wert.

HolgerX 17. Nov 2018 15:55

AW: Elemente aus TStringList in Laufzeit entfernen
 
Hmm..

Delphi-Quellcode:
Begin
      Input:= E_UserGuess.Text;
      E_UserGuess.Text:= '';

// Hier greifst Du auf Vocabulary zu. Wann wurde dort etwas reingeladen?
      Answer:=AnsiCompareStr(Vocabulary.Names[RandomNumber], Input);

          RepetitionCheck:=RandomNumber;                                          
          While RepetitionCheck = RandomNumber Do RandomNumber:=random(WordCount);

          try
// Hier wird Vocabulary 'Überschreiben'
            Vocabulary:= TStringList.Create;                                
            Vocabulary.LoadFromFile('Vocabulary.txt');                    
            L_UnknownWord.Caption:= Vocabulary.ValueFromIndex[RandomNumber];    
            finally
// Hier wird Vocabulary 'weggeschmissen
            Vocabulary.Free;
          end;

    end

Siehe meine Kommentare..

Woher kommt beim ersten Zugriff auf Vocabulary der Inhalt und was meinst Du passiert beim nächsten Zugriff auf Vocabulary?

DieDolly 17. Nov 2018 16:07

AW: Elemente aus TStringList in Laufzeit entfernen
 
Zitat:

Woher kommt beim ersten Zugriff auf Vocabulary der Inhalt und was meinst Du passiert beim nächsten Zugriff auf Vocabulary?
Post 21 löst viele der Probleme :thumb:

KetchUp 17. Nov 2018 16:27

AW: Elemente aus TStringList in Laufzeit entfernen
 
Zitat:

Zitat von DieDolly (Beitrag 1418330)
Post 21 löst viele der Probleme :thumb:

Vielen Dank @ DieDolly für die ausführliche Erklärung. :thumb:
Kann ich Vokabeln auch wieder aus der txt Datei laden, sodass man die ständig wechseln kann?

Zitat:

Zitat von HolgerX (Beitrag 1418329)

Delphi-Quellcode:
// Hier greifst Du auf Vocabulary zu. Wann wurde dort etwas reingeladen?
      Answer:=AnsiCompareStr(Vocabulary.Names[RandomNumber], Input);

Vocabulary wird in FormCreate erstellt. Aber es wird nicht an die Prozedur weitergegeben obwohl Vocabulary global deklariert ist.
Zitat:

Zitat von HolgerX (Beitrag 1418329)
Delphi-Quellcode:
     
            finally
// Hier wird Vocabulary 'weggeschmissen
            Vocabulary.Free;
          end;

    end

Oh, das wusste ich nicht. Was ist denn die genaue Funktion von ".Free" ?

DieDolly 17. Nov 2018 16:29

AW: Elemente aus TStringList in Laufzeit entfernen
 
Zitat:

Kann ich Vokabeln auch wieder aus der txt Datei laden, sodass man die ständig wechseln kann?
Wofür erneut aus der Textdatei laden?

Ich hab dir bei Eine zufällige englische Vokabel anzeigen doch gezeigt wie man eine Vokabel aus den Klassen lädt. Die Txt-Datei brauchst du nach Programmstart nur ein einziges mal laden. Danach nie wieder. Das ist ja der Sinn der Sache.

KetchUp 17. Nov 2018 16:37

AW: Elemente aus TStringList in Laufzeit entfernen
 
Zitat:

Zitat von DieDolly (Beitrag 1418335)
Zitat:

Kann ich Vokabeln auch wieder aus der txt Datei laden, sodass man die ständig wechseln kann?
Wofür erneut aus der Textdatei laden?

Ich meinte weil Du die Vokabeln direkt im Quellcode stehen hast. Die müssen variabel sein.


PS: Ich hab gerade das Problem gefunden. Es lag tatsächlich am .Free nach finally. Jetzt funktioniert es scheinbar.

DieDolly 17. Nov 2018 16:39

AW: Elemente aus TStringList in Laufzeit entfernen
 
Zitat:

Die müssen variabel sein.
Du musst du ja auch selber reinladen. Das war nur ein Beispiel.
Du kannst 99% von meinem Code übernehmen. Du musst sie nur selber reinladen.

Ungefähr so

Delphi-Quellcode:
try
 Vocabulary:= TStringList.Create;
 Vocabulary.LoadFromFile('Vocabulary.txt');
 
 for i := 0 to Vocabulary.Count - 1 do
  begin
   Vocab := TVocab.Create;
   Vocab.SolvedCount := 0;
   Vocab.German := Vocabulary.Names[i];
   Vocab.English := Vocabulary.ValueFromIndex[i];
   VokabelListe.Add(Vocab);
  end;
finally
 Vocabulary.Free;
end;

KetchUp 17. Nov 2018 16:48

AW: Elemente aus TStringList in Laufzeit entfernen
 
Zitat:

Zitat von DieDolly (Beitrag 1418340)
Delphi-Quellcode:

finally
 Vocabulary.Free;
end;

Was hat denn das .Free am Ende für eine Bedeutung/Funktion?

DieDolly 17. Nov 2018 16:49

AW: Elemente aus TStringList in Laufzeit entfernen
 
Du gibst den reservierten Speicher der StringListe wieder frei.

HolgerX 17. Nov 2018 18:49

AW: Elemente aus TStringList in Laufzeit entfernen
 
Hmm..

Zitat:

Zitat von DieDolly (Beitrag 1418340)
Zitat:

Die müssen variabel sein.
Du musst du ja auch selber reinladen. Das war nur ein Beispiel.
Du kannst 99% von meinem Code übernehmen. Du musst sie nur selber reinladen.

Ungefähr so

Delphi-Quellcode:
try
 Vocabulary:= TStringList.Create;
 Vocabulary.LoadFromFile('Vocabulary.txt');
 
 for i := 0 to Vocabulary.Count - 1 do
  begin
   Vocab := TVocab.Create;
   Vocab.SolvedCount := 0;
   Vocab.German := Vocabulary.Names[i];
   Vocab.English := Vocabulary.ValueFromIndex[i];
   VokabelListe.Add(Vocab);
  end;
finally
 Vocabulary.Free;
end;

Umd das vielleicht noch zu verdeutlichen, schön in eine Ladeprocedure verpackt:

Delphi-Quellcode:
procedure LoadVocab(VokabelListe : TList<TVocab>);
var
  tmpVocabulary : TStringList;
  Vocab : TVocab;
begin
  try
   tmpVocabulary:= TStringList.Create;
   tmpVocabulary.LoadFromFile('Vocabulary.txt');
 
   for i := 0 to Vocabulary.Count - 1 do
    begin
     Vocab := TVocab.Create;
     Vocab.SolvedCount := 0;
     Vocab.German := tmpVocabulary.Names[i];
     Vocab.English := tmpVocabulary.ValueFromIndex[i];
     VokabelListe.Add(Vocab);
    end;
  finally
   tmpVocabulary.Free;
  end;
end;
(Ungetestet, nur so hingeschrieben ;) )

@KetchUp

Oder wenn Du unbedingt mit der StringList weiter arbeiten möchtest, dann solltest Du dir erstmal über einen grundsätzlichen Ablauf klar sein..

z.B.:

FormCreate
-> Laden der Vokabelliste in die StringList

Im (wahrscheinlich) ButtonClick
-> Prüfen/Arbeiten MIT der Stringliste
-> Nicht wieder neu laden, wozu auch, ist ja bereits

FormClose
-> Mit .Free die Stringliste wieder freigeben (aufräumen!!)

KetchUp 18. Nov 2018 07:56

AW: Elemente aus TStringList in Laufzeit entfernen
 
Ich möchte es erstmal mit der TStringList Variante probieren. Das Programm muss auch noch ein paar andere Sachen können wie zum Beispiel die Lernrichtung (Deutsch>Englisch oder Englisch>Deutsch) ändern.
Deswegen sieht mein Ansatz jetzt so aus:

Delphi-Quellcode:
Begin
  If Vocabulary.Count > 0 Then

    Begin
      If GermanEnglish = True

      Then
        Begin
          Input:= E_UserGuess.Text;
          E_UserGuess.Text:= '';

          Answer:=AnsiCompareStr(Vocabulary.Names[RandomNumber], Input);

          If Answer=0
          Then
            Begin
              L_CorrectAnswer.Caption:='';
              Img_FeedBack.Picture.Bitmap.Assign(jpgCorrect);
              //jpgCorrect.free;
              Vocabulary.Delete(RandomNumber);
            End

          Else
            Begin
              L_CorrectAnswer.Caption:='Deine Antwort: '+(Input)+'  '+'Richtige Antwort: '+(Vocabulary.ValueFromIndex[RandomNumber]);
              Img_FeedBack.Picture.Bitmap.Assign(jpgWrong);
              //jpgWrong.free;
            End;

            RepetitionCheck:=RandomNumber;
            While RepetitionCheck = RandomNumber Do RandomNumber:=random(Vocabulary.Count);

            try
              L_UnknownWord.Caption:= Vocabulary.ValueFromIndex[RandomNumber];
              L_RemainingWords.Caption:= 'Verbleibende Vokabeln: '+IntToStr(Vocabulary.Count);
              L_RemainingWords.Font.Name:='Helvetica LT Std';
              L_RemainingWords.Font.Size:= 16;
              L_RemainingWords.Font.Color:= RGB(170,220,70);
              finally
            end;
        end

      Else
        Begin
          Input:= E_UserGuess.Text;
          E_UserGuess.Text:= '';

          Answer:=AnsiCompareStr(Vocabulary.ValueFromIndex[RandomNumber], Input);

          If Answer=0
          Then
            Begin
              L_CorrectAnswer.Caption:='';
              Img_FeedBack.Picture.Bitmap.Assign(jpgCorrect);
              jpgCorrect.free;
              Vocabulary.Delete(RandomNumber);
            End

          Else
            Begin
              L_CorrectAnswer.Caption:='Deine Antwort: '+(Input)+'  '+'Richtige Antwort: '+(Vocabulary.Names[RandomNumber]);
              Img_FeedBack.Picture.Bitmap.Assign(jpgWrong);
              jpgWrong.free;
            End;

            RepetitionCheck:=RandomNumber;
            While RepetitionCheck = RandomNumber Do RandomNumber:=random(Vocabulary.Count);

            try
              L_UnknownWord.Caption:= Vocabulary.Names[RandomNumber];
              L_RemainingWords.Caption:= 'Verbleibende Vokabeln: '+IntToStr(Vocabulary.Count);
              L_RemainingWords.Font.Name:='Helvetica LT Std';
              L_RemainingWords.Font.Size:= 16;
              L_RemainingWords.Font.Color:= RGB(170,220,70);
              finally
              //Vocabulary.Free;
            end;
        End;
    End

  Else
    Begin
      Form3 := TForm3.Create(self);
        try
          Form3.ShowModal;
        finally
          Form3.Free;
          Vocabulary.Free;
        end;
    End;
End;
Nachdem alle Vokabeln (in dem Fall) einmal richtig waren, soll ein neues Fenster geöffnet werden. Aber genau an der Stelle stürzt das Programm immer ab. Wo muss ich Vocabulary.Free; platzieren damit das funktioniert?

Delphi.Narium 18. Nov 2018 09:53

AW: Elemente aus TStringList in Laufzeit entfernen
 
Zitat:

Zitat von KetchUp (Beitrag 1418360)
Wo muss ich Vocabulary.Free; platzieren damit das funktioniert?

Nirgendwo (jedenfalls nicht in dieser Routine).

Wo erstellst Du die Liste ubd wo lädst Du die Liste?

Im FormCreate?
Dann gehört das Vocabulary.Free ins FormDestroy.

Sinnvollerweise solltest Du die Liste beim Programmstart erstellen (unabhängig davon ob Du sie dort sofort lädst oder erst später).

Freigeben solltest Du sie dann beim Programmende.

Wenn Du sie unbedingt leeren möchtest, so kannst Du an der Stelle, an der momentan das Vocabulary.Free steht, ein Vocabulary.Clear aufrufen. Dann wird die Liste geleert, aber nicht zerstört.

KetchUp 18. Nov 2018 10:29

AW: Elemente aus TStringList in Laufzeit entfernen
 
Zitat:

Zitat von Delphi.Narium (Beitrag 1418364)

Wo erstellst Du die Liste ubd wo lädst Du die Liste?

Im FormCreate?
Dann gehört das Vocabulary.Free ins FormDestroy.

Hab ich jetzt auch so gemacht.

Delphi-Quellcode:
 If Vocabulary.Count > 0 Then

//mach was

  Else
    Begin
      FormDestroy(Vocabulary);
    End;
Sobald die Bedingung nicht mehr erfüllt ist stürzt er aber ab. Er kommt garnicht dazu die Prozedur FormDestroy aufzurufen.

DieDolly 18. Nov 2018 10:59

AW: Elemente aus TStringList in Laufzeit entfernen
 
Zitat:

Das Programm muss auch noch ein paar andere Sachen können wie zum Beispiel die Lernrichtung (Deutsch>Englisch oder Englisch>Deutsch) ändern.
Ein Grund mehr das mit Klassen zu machen :roll:

Und wenn du es schon komplizierter machst als es sein muss und ehrlich gesagt auch irgendwie falsch, dann entferne wenigstens diesen einen Fehler hier.
Alle anderen kannst du drin lassen denn sonst bleibt kein Code mehr übrig.
Delphi-Quellcode:
If GermanEnglish = True

EWeiss 18. Nov 2018 11:19

AW: Elemente aus TStringList in Laufzeit entfernen
 
Zitat:

Zitat von DieDolly (Beitrag 1418368)
Zitat:

Das Programm muss auch noch ein paar andere Sachen können wie zum Beispiel die Lernrichtung (Deutsch>Englisch oder Englisch>Deutsch) ändern.
Ein Grund mehr das mit Klassen zu machen :roll:

Und wenn du es schon komplizierter machst als es sein muss und ehrlich gesagt auch irgendwie falsch, dann entferne wenigstens diesen einen Fehler hier.
Alle anderen kannst du drin lassen denn sonst bleibt kein Code mehr übrig.
Delphi-Quellcode:
If GermanEnglish = True

Es ist kein Fehler nur eine Unart!

Das reicht auf True muss man nicht prüfen..
Delphi-Quellcode:
If GermanEnglish then


oder
Delphi-Quellcode:
If not GermanEnglish then


anstelle von
Delphi-Quellcode:
If GermanEnglish = false then


gruss

DieDolly 18. Nov 2018 11:24

AW: Elemente aus TStringList in Laufzeit entfernen
 
Zitat:

Es ist kein Fehler nur eine Unart!
So hätte ich es besser auch genannt.

Delphi.Narium 18. Nov 2018 11:30

AW: Elemente aus TStringList in Laufzeit entfernen
 
Zitat:

Zitat von KetchUp (Beitrag 1418366)
Zitat:

Zitat von Delphi.Narium (Beitrag 1418364)

Wo erstellst Du die Liste ubd wo lädst Du die Liste?

Im FormCreate?
Dann gehört das Vocabulary.Free ins FormDestroy.

Hab ich jetzt auch so gemacht.

Delphi-Quellcode:
 If Vocabulary.Count > 0 Then

//mach was

  Else
    Begin
      FormDestroy(Vocabulary);
    End;
Sobald die Bedingung nicht mehr erfüllt ist stürzt er aber ab. Er kommt garnicht dazu die Prozedur FormDestroy aufzurufen.

Du darfst die Liste nicht in der Routine freigeben, sondern nur und ausschließlich nur in der Methode FormDestroy. Und die Methode FormDestroy darfst Du nicht selbst aufrufen, das geschieht automatisch beim Programmende, genauso wie beim Programmstart FormCreate automatisch aufgerufen wird.

Die Liste in Deiner oben geposteten Routine freizugeben ist schlicht und einfach (bei der jetztigen Form der Implementierung) unsinnig und absolut kontraproduktiv.

Lass es doch bitte einfach endlich weg.

Bitte poste mal den vollständigen Quelltext, den Du bisher geschrieben hast. Mit den Fragmenten ist es nur ein Rumgestocher, wo welcher Fehler herkommen könnte und wie man ihn beheben könnte, wenn man die Abhängigkeiten innerhalb des gesamten Programmes nicht kennt.

EWeiss 18. Nov 2018 11:33

AW: Elemente aus TStringList in Laufzeit entfernen
 
Zitat:

Du darfst die Liste nicht in der Routine freigeben
Eventuell fehlt ihm etwas Mayo :) <> Ketchup
sorry das musste sein.

gruss

DieDolly 18. Nov 2018 11:38

AW: Elemente aus TStringList in Laufzeit entfernen
 
Oder der Willen, es endlich mit den Klassen zu machen. Dann braucht er die SttringListe, seinen Gegner, nur noch einmalig beim Programmstart.
Ich habe vor 10 Jahren auch mal einen Vokabeltrainer gemacht und der baute auch auf StringListen auf, weil ich damals nix anderes kannte. Sei doch froh, dass dir hier direkt ein sehr viel besserer Weg vorgeschlagen wird. Der ist nicht nur für dich besser, sondern auch für deine Zensur.


Alle Zeitangaben in WEZ +1. Es ist jetzt 03:46 Uhr.
Seite 1 von 3  1 23      

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