List index out of bounds bei TStringList



  • Habe die Suchfunktion mehrmals benutzt, doch keine Lösung gefunden.. :-\

    TStringList* Zeit = new TStringList();
    // z.B. 99:99:99 in 99 Stunden, 99 Minuten usw. splitten
            Zeit->Delimiter = ':';
            Zeit->DelimitedText = dynamic_cast<TLabel*>(Form1->Components[i])->Caption;
    // i wurde schon vorher ein Wert zugeschrieben.
            Stunden  = StrToInt(Zeit->Strings[0]);
            Minuten  = StrToInt(Zeit->Strings[1]);
            Sekunden = StrToInt(Zeit->Strings[2]);
    

    Doch es kommt der Fehler:
    EStringListError 'List index out of bounds (0)'

    😕

    Merci
    Psychomann



  • An welcher Stelle kommt denn der Fehler?
    Hast Du Dir mal angeschaut, was eigentlich DelimitedText zugewiesen wird?
    Welchen Wert hat denn die Eigenschaft Count?

    Gruß,

    Alexander



  • Der Fehler kommt, wo die Funktion aufgerufen wird..

    void __fastcall TSuperForm::BauenClick(TObject *Sender)
    {
            Vorgang();
    } // <- in dieser Zeile
    

    Habe mal ShowMessage(Zeit->Count) eingebaut und es wurde "0" angezeigt..
    Da liegt wahrscheinlich der Fehler. Muss ich das manuell auf 3 stellen?
    *EDIT: Beim Versuch kam der Fehler TStrings::Count ist not accessible EDIT*

    und

    dynamic_cast<TLabel*>(Form1->Components[i])->Caption;
    

    ist ein String wie: "12:23:56"



  • Ich frage mich, was in Vorgang() passiert.

    Psychomann schrieb:

    Habe mal ShowMessage(Zeit->Count) eingebaut und es wurde "0" angezeigt.

    Dann ist es doch kein Wunder, wenn Du einen IndexOutOfBounds-Fehler bekommst.
    Warum hast Du eigentlich diesen dynamic_cast drin? Hast Du mehrere Labels o.ä., die Du damit durchwanderst?
    Vielleicht zeigst Du mal einfach mehr Code und beschreibst auch mal, was Du eigentlich erreichen willst.

    Gruß,

    Alexander



  • Psychomann schrieb:

    dynamic_cast<TLabel*>(Form1->Components)->Caption;
    

    ist ein String wie: "12:23:56"*

    Höchstwahrscheinlich eben nicht. Lass dir den String mal testhalber ausgeben, bevor du ihn [i]DelimitedText* zuweist.



  • Hier der Code:

    void Bauvorgang()
    {
    // Alle Komponenten nach TRadioButton durchsuchen........
    // Falls gefunden, dann alle auf Enabled = false stellen.
            for (int i = 1; i < Form1->ComponentCount; i++)
            {
                    if (Form1->Components[i]->ClassNameIs("TRadioButton"))
                    {
                            dynamic_cast<TRadioButton*>(Form1->Components[i])->Enabled = false;
    // Welches Gebäude wurde gebaut?
                            if (dynamic_cast<TRadioButton*>(Form1->Components[i])->Checked == true)
                            {
                                    for (int h = 1; h <= 19; h++)
                                    {
    // Sicherung der Nummer der Komponente und der Zahl
    // hinter dem Namen: BuildingX (z.B. x = 8)
                                            if (dynamic_cast<TRadioButton*>(Form1->Components[i])->Name == "Building" + IntToStr(h))
                                            {
                                                    GebaeudeBau1 = h;
                                                    GebaeudeBau2 = i;
                                            }
                                    }
                            }
                    }
            }
    
            TStringList* Zeit = new TStringList();
    // z.B. 99:99:99 in 99 Stunden, 99 Minuten usw. splitten
            Zeit->Delimiter = ':';
            Zeit->DelimitedText = dynamic_cast<TLabel*>(Form1->Components[GebaeudeBau2])->Caption;
            Stunden  = StrToInt(Zeit->Strings[0]);
            Minuten  = StrToInt(Zeit->Strings[1]);
            Sekunden = StrToInt(Zeit->Strings[2]);
    
    // Alle Labels mit "Dauer" am Anfang in der Property
    // Name umstellen
            for (int i = 1; i < Form1->ComponentCount; i++)
            {
                    if (Form1->Components[i]->ClassNameIs("TLabel"))
                    {
                            for (int h = 1; h <= 20; h++)
                            {
                                    if (dynamic_cast<TLabel*>(Form1->Components[i])->Name == "Dauer" + IntToStr(h))
                                            dynamic_cast<TLabel*>(Form1->Components[i])->Caption = "Bauvorgang läuft...";
                            }
                    }
            }
    
    // Timer starten
            Form1->BuildingZeit->Enabled = true;
    }
    

    Das geht so. Es gibt 20 RadioButtons, die für 20 Gebäude stehen. Ein Button ist da, der ruft Bauvorgang() auf, sonst nichts. Die Labels (, wo die Zeit steht) heissen: Dauer1 bis Dauer20. Die dazugehörigen RadioButtons (Gebäude) sind Building1 bis Building20.



  • Also, wenn ich das richtig herauslese, dann ist Form1->Components[GebaeudeBau2] wahrscheinlich kein TLabel, sondern ein TRadioButton,
    da GebaeudeBau2 der Index der Komponente ist, die in der ersten if-Bedingung auf ClassNameIs("TRadioButton") abgeprüft wird.
    Der Code ist einigermaßen schwer verständlich und ich verstehe auch nicht, warum hier eine Schleife durchlaufen wird, um dann einen
    Wert zu setzen und daraus die Zeit zu lesen???
    Ich denke, es wäre sehr viel einfacher und übersichtlicher, anstatt dem ganzen dynamic-gecaste drei Arrays zu definieren, die die
    benötigten Komponenten aufnehmen und diese dann in einer for-Schleife durchzugehen.

    Wenn Du schon dynamic_cast verwendest, solltest Du auch überprüfen, ob der Rückgabewert nicht null ist.
    Konstrukte wie

    if (dynamic_cast<TRadioButton*>(Form1->Components[i])->Name == "Building" + IntToStr(h))
    

    können auch ganz schön daneben gehen. Der cast ist hier ohnehin unnötig, da Name eine Standardeigenschaft aller Komponenten ist.

    Du könntest Dir, wenn wirklich alles dynamisch gemacht werden muss, auch mal FindComponent() anschauen. Damit könntest Du Dir dann wenigstens
    die vielen unübersichtlichen Schleifen sparen.

    Gruß,

    Alexander



  • 😃 verdammt, stimmt ja. Danke dir. Das war der Fehler.

    Habe es jetzt mit Arrays probert und es funktioniert einwandfrei.

    Psychomann


Anmelden zum Antworten