Struct als Object in TStringList



  • Wäre nicht TList oder TListObjekt eine Alternative?



  • Wieso willst Du einen AnsiString überhaupt als Objekt in die StringList einfügen?? Dafür brauchst Du doch nur Add() zu verwenden.



  • @Christian211

    Die VCL-Listenklassen haben den Nachteil (meine Meinung), dass man hier grundsätzlich nur Pointer einspeichern kann. So muß man immer casten und die Speicherverwaltung genau im Auge behalten. Bei Einsatz von STL-Containern und (kleineren) Klassen oder Objekten entfällt das. Zudem kann man die vielen schönen Sachen aus <algorithm> darauf anwenden.



  • weil ich 2 strings brauche die zum schluss einen ergeben und ich anch einem auch sorteiren muss 🙂

    sprich - wenn gewünschte logfiles auf zeiten analysiert werde.

    ich muss sagen aus welchem logfile das stammt und sorteiert ausgeben
    bedeutet die logfiles werden gemischt 🙂
    es funzt auch 🙂

    class Client : public TObject
                    {
                            public : AnsiString Pfad;
                    };
    
    .
    .
    .
    for(int a=0 ; a<AusgabeListe->Count ; a++)
                    {
    
                            ErrorLB->Items->Add((AnsiString) static_cast<Client*> (AusgabeListe->Objects[a])->Pfad + "  " + AusgabeListe->Strings[a]);
                    }
    

    nur leider funzt in der listbox "\t" net 😞



  • Was ist das denn?
    Das hier

    for(int a=0 ; a<AusgabeListe->Count ; a++)
    {
      ErrorLB->Items->Add(AusgabeListe->Objects[a]->Pfad + "  " + AusgabeListe->Strings[a]);
    }
    

    sollte auch gehen (falls Objects vom Typ Client ist).



  • habe das mal eben ersetz - nein, das geht leider nicht



  • Was geht nicht? Wie lautet die Fehlermeldung?
    Bitte gewöhne dir vollständigere Fehlerbeschreibungen an. Der Typ von AusgabeListe und Objects wäre auch nicht schlecht.



  • Pfad ist kein Element von TObject

    AusgabeListe ist eine TStringList



  • also für dich:
    da fehlt nur noch die workstatiosn in pfad statt i

    class TClient : public TObject
            {
                    public : AnsiString Pfad;
            };
            TimeForm->ShowModal();
            AnsiString TimeStamp = TimeForm->TimeStamp;
            int range = TimeForm->minuten_plus;
            if(TimeStamp != NULL)
            {
                    MehrfachAuswahl = 1;
                    TList *auswahl = new TList;
                    TStringList *PfadNamen = new TStringList;
                    tree->GetSelections(auswahl);
                    AnsiString Pfad;                //der pfad der datei
                    for(int i=0 ; i<auswahl->Count ;i++)
                    {
                            PfadNamen->Add(PfadAusNode((TTreeNode*)(*auswahl)[i])); //den pfadnamen aus dem selektierten rausholen un hinzufügen
                    }
                    ErrorLB->Clear();       //einmal bitte säubern :)
                    //-----------------------------------------------------------------------------------
    
                    TStringList *AusgabeListe = new TStringList;
                    AusgabeListe->Sorted = 1;
    
                    for(int i=0 ; i<PfadNamen->Count ; i++)
                    {
                            TStringList *LogFile = new TStringList;
                            try
                            {
                                    LogFile->LoadFromFile(PfadNamen->Strings[i]);   //den pfadnamen laden
                            }
                            catch(...)
                            {
                                    ShowMessage("Fehler beim Laden der Datei");
                                    delete LogFile;
                                    delete PfadNamen;
                                    return;
                            }
                            //-----------------------------------------------------------------------------------
                            for(int zeile=0 ; zeile<LogFile->Count ; zeile++)
                            {
                                    //16 zeichen ist der timestamp big
                                    AnsiString Sub = LogFile->Strings[zeile].SubString(0,16);
    
                                    TClient *Workstation = new TClient;     //der pfad
    
                                    Workstation->Pfad = i;
                                    if(Sub == TimeStamp)
                                    {
                                            while(Sub == TimeStamp)
                                            {
                                                    Sub = LogFile->Strings[zeile].SubString(0,16);
                                                    if(Sub == TimeStamp)
                                                    {
                                                            AusgabeListe->AddObject(LogFile->Strings[zeile], Workstation); //objekt hinzufügen damit wir später die workstation mit ausgteben können
                                                    }
                                                    zeile++;
                                            }
                                            break;
                                    }//if sub == timestamp
                            delete Workstation;
                            }//zeile < LogFile->Count
                            delete LogFile;
                    }
    
                    AusgabeListe->Sort();
                    for(int index=0 ; index<AusgabeListe->Count ; index++)
                    {
                            //ErrorLB->Items->Add((AnsiString) static_cast<TClient*> (AusgabeListe->Objects[index])->Pfad + "  " + AusgabeListe->Strings[index]);
                            ErrorLB->Items->Add(AusgabeListe->Objects[index]->Pfad + "  " + AusgabeListe->Strings[index]);
                    }
    
                    delete PfadNamen;
                    delete AusgabeListe;
    
            }
    
            //-----------------------------------------------------------------------------------
            else
            {
                    return;
            }
    }
    


  • @Braunstein

    Tja, programiere zu Hause gerade so ein bisssschen an einem HTML-Parser. Dazu benutzte ich DYNAMIC ARRAY. Wollte ich mal ausprobieren. Tja, und dann wollte ich löschen..... Und dann wollte ich nur noch vector.

    Joo, mir war schon klar, dass die STL besser ist, warum wir hier so stark jetzt TStringList bevorzugt??



  • Dann so

    for(int a=0 ; a<AusgabeListe->Count ; a++)
    {
      ErrorLB->Items->Add(static_cast<TClient*> (AusgabeListe->Objects[a])->Pfad + AnsiString("  ") + AusgabeListe->Strings[a]);
    }
    


  • Christian211 schrieb:

    warum wir hier so stark jetzt TStringList bevorzugt??

    Weil die Dokumentation der STL in Englisch ist?

    Ansonsten fällt mir auf, das TClient* Workstation am Ende der Routine gelöscht wird. Somit ist der Zeiger in der StringList natürlich ungültig und nicht mehr verwendbar.



  • @Christian211
    Für den eigentliche Zweck, Listen von AnsiStrings zu verwalten, ist TStringList ja auch gut geeignet. Diese Object-Eigenschaft finde ich aber nicht so gut. Es gibt sicher Fälle wo man die sinnvoll einsetzen kann. Insbesondere bei TListBox oder TStringGrid lassen sich sehr gut Objekte mit sichtbaren (und anklickbaren) Items verbinden. Für alles andere nehme ich vector, deque oder map.



  • Joe_M. schrieb:

    Christian211 schrieb:

    warum wir hier so stark jetzt TStringList bevorzugt??

    Weil die Dokumentation der STL in Englisch ist?

    Ansonsten fällt mir auf, das TClient* Workstation am Ende der Routine gelöscht wird. Somit ist der Zeiger in der StringList natürlich ungültig und nicht mehr verwendbar.

    klar
    das funzt perfektly



  • warum StrinList verwendet wird, Christian?
    WEil du es mir angeschnackt hast und ich noob 80% der fragen stelle 🙂
    🕶



  • Braunstein schrieb:

    Dann so

    for(int a=0 ; a<AusgabeListe->Count ; a++)
    {
      ErrorLB->Items->Add(static_cast<TClient*> (AusgabeListe->Objects[a])->Pfad + AnsiString("  ") + AusgabeListe->Strings[a]);
    }
    

    ja, so geht es jetz
    aber das ist das geliche wie bei mir, nur das das (AnsiString) woanders steht 😉



  • dern00b schrieb:

    Joe_M. schrieb:

    Ansonsten fällt mir auf, das TClient* Workstation am Ende der Routine gelöscht wird. Somit ist der Zeiger in der StringList natürlich ungültig und nicht mehr verwendbar.

    klar
    das funzt perfektly

    Jau, dann wunder dich aber nicht, wenn es dann in absehbarer Zeit Access-Violations gibt... und das WIRD früher oder später passieren.



  • nein. denn so wie ich es verstanden habe ist das element drin.
    und das gelöschte element hat ddamit dann NIX mehr zu tun, weil sonst würde es ja net klappen mit der ausgabe - ODER?



  • Joe_M. schrieb:

    Weil die Dokumentation der STL in Englisch ist?

    und das ist so ein großes problem?

    wenn man hier so liest, fragt man sich ob manche schon von OOP gehört ham. was hier so mit StringListen rumgedoktort wird, anstatt sich ne kleine feine klasse zu schreiben die nur noch nen compare-functor hat und die sortierung sort() überläßt.

    @dernoob

    -> try-catch würde ich nie in schleifen packen, erzeugen zu viel overhead
    -> in schleifen niemals neue objekte anlegen wenn man es vermeiden kann -> overhead
    -> code übersichtlicher gestalten (ist ja extrem verschachtelt)



  • Der Pointer ist natürlich noch in der Liste, er zeigt nach dem Löschen aber auf uninitialisierten Speicher. Die Verwendung eines solchen Pointer erzeugt undefiniertes Verhalten.


Anmelden zum Antworten