Struct als Object in TStringList



  • 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.



  • Sunday schrieb:

    @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)

    was ist overhead? übersicht? hö?

    code übersichtlicher gestalten? ich habe echt mein bestes gegeben. sitze hier gerade mit dem chefprogrammierer und der verzweifelt gerade - er ist der meinung ich habe es falsch gemacht, wei ich die objekte wieder gelöscht habe - er gibt euch recht.... aber hinkriegen tut er es auch net......

    warum kein try in schleifen? und wenn es sonst net anders geht? also ich sehe sonstzz keine andere möglichkeit....



  • Sunday schrieb:

    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.

    wenn sich das auf mich bezieht:
    ich sehe keinen grund hier ne klasse zu machen. weil ich habe hier sooo viel verschiedene sachen zu bewältigen:
    analysieren auf zeit, auf error, auf hangings, auf patienten, und und und.
    dann mehrere gleichzeitig analysieren. ich habe auch nur 3 wochen zeit. ich bin kein profi und net der schnellste - definitv auch net dam lam0r. also da noch ne klasse zu basteln etc. sehe ich net ein



  • Ich hab deinen Quelltext mal ein bischen geändert. Ich habs aber nicht getestet.

    // Client geändert
      struct TClient
      {
         AnsiString tstamp, Pfad;
         TClient(const AnsiString& t, const AnsiString& p) : tstamp(t), Pfad(p) {} //Konstruktor wird zum Einfügen in den vector benötigt
      };
      // < Operator für TClient erzeugt wegen sort
      bool operator< (const TClient& lhs, const TClient& rhs)
      {
      	return lhs.tstamp < rhs.tstamp;
      }
      vector<TClient> AusgabeListe; // AusgabeListe in vector geändert (ohne Pointer)
    
      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 :)
         //-----------------------------------------------------------------------------------
    
         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);
    
                if(Sub == TimeStamp)
                {
                   while(Sub == TimeStamp) // while Schleife etwas umgebaut
                   {
                      AusgabeListe.push_back(TClient(LogFile->Strings[zeile], IntToStr(i))); //objekt hinzufügen damit wir später die workstation mit ausgteben können
                      Sub = LogFile->Strings[zeile++].SubString(0,16);
                   }
                }
             }
             delete LogFile;
         }
    
         sort(AusgabeListe.begin(), AusgabeListe.end()); //sortieren
         for(int index=0 ; index<AusgabeListe->Count ; index++)
         {
             ErrorLB->Items->Add(AusgabeListe[index].Pfad + "  " + AusgabeListe[index].tstamp);
         }
    
         delete PfadNamen;
         delete AusgabeListe;
    
      } else return;
    }
    


  • ich habe gaaaaaaaaaaaaaaaanz viele fehler 😞
    ich weiß nicht - aber bei meinem hat zumindest alles funktioniert...

    bei eurem - das bestimmt richtiger ist - habe ich fehler und ich verstehe den QC nicht mal mehr. in sofern kann ich da auch nix ausbessern

    bool operator< (const TClient& lhs, const TClient& rhs)
      {
          return lhs.tstamp < rhs.tstamp;
      }
      vector<TClient> AusgabeListe; // AusgabeListe in vector geändert (ohne Pointer)
    

    zum beispiel da kann ich nix mit anfangen
    push_back()???

    wie egsagt - ich kapiere es nicht
    ist warscheinlich alles noch ne stufe zu hoch



  • an alle die geholfen haben. ich saß jetzt ne std mit dem chefprogger hier
    un der hat gecastet und hier und da, und pointer, adressen alles ausprobiert und debuggt wie der freak....

    ES GEHT NICHT!!! Er versteht es noch nichtmal wieso es nicht geht. und auch ein andere Programmierer kam dann hinzu. Es klappte nicht. Immer diese Zugriffsverletzungen.. einzig und alleine meine erstlösung funktioniert. und auch das verstanden die beiden nicht. wobei ehrlich gesagt für mich meine lösung logisch ist(sonst hätt ichs warscheinlich acuh net so gemacht 😉 )

    wie egsagt. dank an euch, und ich habe jetzt meine erstlösung hier - so wie ichs auch gepostet habe.
    vllt hat irgendwer mal die lösung was STringList::AddObject() amcht, weil auch in der hilfe steht, das man das übergebene objekt selber frewigeben muss.... naja..



  • sorry, aber du solltest dich mal mit den grundlagen von C++/OOP-Programmieren beschäftigen.

    dern00b schrieb:

    bool operator< (const TClient& lhs, const TClient& rhs)
      {
          return lhs.tstamp < rhs.tstamp;
      }
      vector<TClient> AusgabeListe; // AusgabeListe in vector geändert (ohne Pointer)
    

    zum beispiel da kann ich nix mit anfangen
    push_back()??? h

    google mal nach nem C++ Tutorial, schau im Thema klassen nach "operatoren".

    dern00b schrieb:

    vllt hat irgendwer mal die lösung was STringList::AddObject() amcht, weil auch in der hilfe steht, das man das übergebene objekt selber frewigeben muss.... naja..

    ja, du musst das Objekt selber freigeben. aber nicht solange du es noch benötigst. Du speicherst nicht das Objekt in der Liste sondern nur den Zeiger darauf!

    du musst das Objekt löschen wenn du es nicht mehr brauchst(meistens ist das der fall, wenn du es mit ->Delete() oder ->Clear() aus der Liste enfehrnst, oder das Programm beendest.
    dazu kannst du zB ->Delete() ->Clear() und den Destruktor von der Klasse überschreiben, oder selber die Objekte vor den entsprechenden funktionen wieder freigeben.

    mfg
    BigNeal


Anmelden zum Antworten