Fehlerbehebung!?!



  • Mvstylez schrieb:

    einen schubs in die richtige richtung bitte 😉

    Wahrscheinlich benutzt Du irgendwo string::substr() mit ungültigen Parametern.
    Z.B. in tokenizer::next() .



  • ah ja hab grade gesehen das es darum ja auch in der fehlermeldung geht und wo der debugger genau den fehler anzeigt... aber ich verstehe trozdem nicht warum der das beim ersten string hinbekommt und beim zweiten mal dann nicht das dürfte doch eigentlich kein unterschied machen myPos usw wird doch neu belegt also dürfte er nicht darüber hinausspringen



  • also ich merk grade dem scheint nicht der fall zu sein so als ob der nach dem einlesen der Zeile nicht merkt das es eine neue Zeile ist und er wieder bei 0 anfangen muss.....
    was logisch ist wenn man vergisst das oben hinzuschreiben 😉 Danke!
    bin ich eigentlich der einzige der so viele Schusselfehler macht wenn es darum geht ein programm zu schreiben bzw. wie kann man da entgegenwirken?



  • nein, das geht vielen am Anfang so. Die C++ Lernkurve ist sehr steil, und mit jeder durchwachten Nacht, die man auf der Suche nach der Ursache eines Schusselfehlers verbracht hat, sinkt die Schusselfehler-Rate, denn eine wegen Debuggings unter Zeitdruck durchwachte Nacht hat einen hervorragenden Lerneffekt (den Fehler macht man wahrscheinlich nicht ein zweites Mal :D)



  • haha ok gut zu wissen dass es hoffentlich irgendwann besser wird 😉
    Der Zwang das nicht allzu oft zu wiederhohlen ist auf alle fälle da...
    jetzt habe ich noch eine Frage zu einem Logik-Problem:
    ich hab jetzt noch die Klasse: Orte und die Klasse Orteliste... jetzt muss ich jeder Reise ein paar Orte und die Aufenthaltsdauer dieser Orte hinzufügen... kann ich dass einfach als ein Feld von int's schreiben die die Position der Orte in Ortlist angeben...
    quasi schnell runtergekrackselt so:

    class Reisen....
    int myOrtID[10]; //sollen maximal 10 orte pro reise sein
    int myOrtlength[10];
    int mySize;
    ...
    };
    
    //woanders ;-)
    
    for (i=0;i<reise.mysize;i++){
    cout<<ortliste[myOrtID[i]]<<" Aufenthaltsdauer"<<reise.myOrtLength;
    }
    

    hoffe das ist ungefähr verständlich wie ich das meine würde das so gehen oder gibt es bessere vorschläge 😉



  • Du solltest deine Klasse besser "Reise" (d.h. in der Einzahl) nennen - und "Ort" (statt "Orte"). Eine gute sinnvolle Benennung ist das A und O.

    Für deine Orte innerhalb der Reise-Klasse solltest du dann eine eigene Struktur anlegen:

    struct ReiseOrt // oder Aufenthalt oder ...
    {
      int OrtIndex; // alternativ: const Ort* (bzw. const Ort&)
      int LengthOfStay;
    }
    

    Und statt des Arrays würde ich einen std::vector<ReiseOrt> vorschlagen.



  • danke für die Antwort. da wir vectors noch nich behandelt haben würde ich das lieber lassen als mich da jetzt kurzfristig reinzulesen 😉
    struct ist doch quasi das gleiche wie class oder hab ich da was falsch verstanden?
    Die Orte habe ich schon in ner extra klasse das problem ist in deinem fall müsste ich ja für jeden Ort der ja bei unterschiedlichen reisen unterschiedliche Aufenthaltsdauern haben kann ein extra object anlegen oder?



  • ach ne nach nochmaligen drüberlesen du meinst das ich neben Ort und Reise noch eine Klasse aufmache "Stay"(was auch immer) und diese klasse dann in den Ort mit einfließen lasse oder?
    also quasi

    class Stay
    { int OrtID
    int LengthOfStay
    }
    
    // und in der class Reise
    class Reise
    {myId
    myLength
    myPrice
    //dann noch das hinzufügen:
    Stay myOrte[];
    mySize
    

    das ergibt Sinn dann vermisch ich die Funktionen/Methoden auch nicht so...
    aber ich verstehe noch nicht ganz wie ich das dann wieder aufrufen kann
    sagen wir mal ich hab in der Reiselist[] 15 reisen stehen und ich müsste ja pro Reise z.B. 10 Orte hinzufügen selbst wenn ich eine klasse StayList mache müsste die ja aus einem 2x2 "feld" bestehen oder damit ich für jede Reise die OrtID's hinbekomme?!?
    bzw. was ich meine wenn ich dieses Stay myOrte[] dann aufrufe muss ich ja sowieso immer die Reise mit angeben erstellt der dann für jede Reise eine eigene Stay myOrte[] oder nur eins für alle?



  • Der Vorteil von der Struktur ist, daß du dann nur noch ein Array hast. In deiner Variante müßtest du ja immer schauen, daß die zugehörigen Werte je Array-Index zusammenpassen (und wenn du ein größeres Array haben möchtest, müßtest du alle Arrays anpassen - anstatt nur das eine).

    Wenn du also

    Stay myOrte[10];
    

    hast, dann kannst du einfach per

    myOrte[index].OrtID
    // bzw.
    myOrte[index].LengthOfStay
    

    auf die Werte zugreifen.

    myOrte ist also genau so eine Membervariable wie in deinem ursprünglichen Code die Variablen myOrtID[10] und myOrtlength[10] - die Verschachtelung ist nur etwas anders.
    Wenn du jetzt noch einen weiteren Wert benötigst, so kannst du dann einfach diesen zu der Struktur Stay hinzufügen (anstatt wiederum ein neues Array davon anzulegen).
    Dies ist generell der Gedanke hinter der objektorientierten Programmierung!



  • Vielen Dank! werde es so ausprobieren und hoffentlich hinbekommen 😉
    Danke!



  • Hab noch ein paar Probleme 😢

    Hab wahrscheinlich irgendwas übersehen..
    Damit will ich quasi die Aufenthalte der Reise hinzufügen aber irgendwie funktioniert das nicht richtig
    1. bei einem gefunden Ort funktioniert es zumindest bis zum speichern der Datei dann hab ich da einen fehler aber da schau ich später mal rein.. aber wieso funktioniert es dann nicht wenn ich den Ort erst neu erstellen muss?
    der Ort wird erstellt und den kann ich mir anzeigen lassen aber die Position des ortes in der Ortliste wird nicht gespeichert?!?

    Reisenlist::Reisenlist():
        mySize(0)
    {
    }
    void Reisenlist::addStay(int id, Ortelist &ortelist){
        bool added=false;
        for(int i=0; i<mySize;i++){
            if (myReiselist.id()==id){
                std::string name;
                int length;
                bool foundOrt=1;
                std::cout<<"\nBitte geben Sie den Namen des Ortes ein: \n";
                std::cin>>std::ws;
                getline(std::cin, name);
                for (int j=0; j<ortelist.getMySize();j++){
                    if(name==ortelist.getMyOrt(j)){
                        std::cout<<"Geben sie die Aufenthaltsdauer an: ";
                        std::cin>>length;
                        myReiselist[i].setStayId(j,length,myReiselist[i].staySize());
                        myReiselist[i].plusStaySize();
                        foundOrt=true;
                        added = true;
                        break;
                    }else{foundOrt=false;
                    }
                }
                    if (!foundOrt){
                        std::cout<<"Geben sie die Aufenthaltsdauer an: ";
                        std::cin>>length;
                        Orte orte(name);
                        ortelist.addOrte(orte);
                        myReiselist[i].setStayId(ortelist.getMySize(),length,myReiselist[i].staySize());
                        myReiselist[i].plusStaySize();
                        added=true;
    
                    }
    
            }
        }
        if (!added)std::cout<<"\nUngültige Reise eingegeben\n";
    }
    

    die methoden dazu:

    #ifndef STAYS_H
    #define STAYS_H
    #include <string>
    
    class Stays
    {
    private:
        int myStayId;
        int myStayLength;
    public:
        Stays();
        Stays(int myStayId,int myStayLength);
        //getter
        int getStayId()const{return myStayId;}
        int getStayLength()const{return myStayLength;}
        //setter
        void setStayId(int stayId){myStayId = stayId;}
        void setStayLength(int stayLength){myStayLength = stayLength;}
        std::string serialize() const;
    };
    
    #endif // STAYS_H
    

    und

    void plusStaySize(){myStaySize+=1;}
    

    in der Reisen Klasse

    2.Problem bei der Ausgabe gibt der anstelle der korrekten Stays immer irgendeine leere Stay klasse aus also kommt bei
    [i] int stayLength(int pos) const{return myStays[pos].getStayLength();}
    int getStayId(int pos) const{return myStays[pos].getStayId();}*
    immer return 0; aber da sollte eigentlich ja die id/aufenthaltsdauer der Reise stehen wenn ich im debugger Die reise selber anschaue steht da auch alles richtig drin und der übergibt die korrekten Werte aber greift irgendwie auf ein anderes myStays zu 😢

    Bei der Ausgabe

    #ifndef REISEN_H
    #define REISEN_H
    #include <iostream>
    #include <string>
    #include "stays.h"
    
    const int MAXORT=10;
    
    class Reisen
    {
    private:
        int myId;
        double myPrice;
        int myLength;
        Stays myStays[MAXORT];
        int myStaySize;
    
    public:
        Reisen();
        Reisen(int myId, double myPrice, int myLength, Stays myStays[MAXORT], int staySize);
        //getter
        int id() const {return myId;}
        double price() const{return myPrice;}
        int length() const{return myLength;}
        int staySize() const{return myStaySize;}
        int stayLength(int pos) const{return myStays[pos].getStayLength();}
        int getStayId(int pos) const{return myStays[pos].getStayId();}
        //setter
        void setId(int id){myId=id;}
        void setStayId(int stayId,int stayLength, int s){myStays[s].setStayLength(stayLength); myStays[s].setStayId(stayId); }
        void setPrice(double price) {myPrice = price;}
        void setLength(int length) {myLength = length;}
        void setStaySize(int staySize){myStaySize = staySize;}
        //andere Methoden
        void createStay(int stayId, int stayLength);
        void plusStaySize(){myStaySize+=1;}
        std::string serialize() const;
    
    };
    std::ostream& operator<<(std::ostream& str, const Reisen& reisen);
    Reisen createReiseFromString(const std::string& s);
    #endif // REISEN_H
    
    #ifndef REISENLIST_H
    #define REISENLIST_H
    #include "reisen.h"
    #include <iostream>
    #include <string>
    #include <ortelist.h>
    
    const int MAXSIZE2=100;
    
    class Reisenlist
    {
    private:
        Reisen myReiselist[MAXSIZE2];
        int mySize;
    public:
        Reisenlist();
        void addReisen(const Reisen& reisen);    
        void readFile(const std::string filename);
        void show( Ortelist ortelist);
        void writeFile(const std::string filename);
        void searchMax();
        void searchMin();
        void preisProTag();
        void addStay(int id,Ortelist &ortelist);
    };
    
    #endif // REISENLIST_H
    
    void Reisenlist::writeFile(const std::string filename){
        std::ofstream fo(filename.c_str());
        if (!fo){
            std::cout<<"Datei "<<filename<<" kann nicht beschrieben werden.\n";
            return;
        }
      //nur zur erklärung
        fo<<"# ID^Preis^Reisenlänge^AnzahlBesuchterOrte\n";
        fo<<"# 2. Zeile: DazugehörendeOrte^Aufenthaltsdauer\n";
        for (int i= 0; i< mySize; i++) {
            fo<<myReiselist[i].serialize()<<std::endl;
            fo<<myReiselist[i].staySize()<<"^";
            for(int j=0;j<myReiselist[i].staySize();j++){
                fo<<myReiselist[i].getStayId(j)<<"^"<<myReiselist[i].stayLength(j)<<"^";
            }
            if (myReiselist[i].staySize()==0){
                fo<<"0^0^0";
            }
            fo<<std::endl;
        }
        fo.close();
    
    }
    

    falls ich was vergessen habe zu posten kommt das gerne noch mit hin..



  • So ganz durchschaue ich deinen Code nicht (die Methode addStay macht m.E. zu viel und sollte auf mehrere kleinere Funktionen aufgeteilt werden).

    Aber besser ist es sowieso, wenn du selber den Fehler findest.
    Was für eine IDE (Editor) verwendest du denn? Am besten, du lernst den Umgang mit dem Debugger (Stichworte: Breakpoint, Watch, CallStack).



  • Ich kann dir leider keine Lösung sagen, aber:
    Stichwort ist hier minimales Beispiel . Manchmal entdeckt man auch selber leicht den Fehler, wenn man versucht das Problem aufs Wesentliche zu beschränken.



  • Verwende QT creator und mit dem Debugger arbeite ich schon aber von watch und Callstacks noch nié was gehört (es sei denn watch bezeichnet einfach die Möglichkeit variableninhalte anzuschauen). Meines erachtens schickt der alles richtig hin und her hab mein beitrag davor nochmal editiert, kann ich dir irgendwas verständlicher machen an dem Code?
    quasi sobald die Id gefunden wurde schaut er ob es den Ort schon gibt oder nicht
    und wenn es ihn gibt sucht er nach der Position in die der Ort gespeichert ist übergibt das an myStayId,
    wenn es ihn nicht gibt legt er einen Neuen Ort an und übergibt die position wo er den neuen Ort gespeichert hat an myStayId

    könnte es daran liegen das ich die ortelist auf eine bestimmte Art übergebe?
    wobei den Ort erstellt es ja 😢



  • f (!foundOrt){
                        std::cout<<"Geben sie die Aufenthaltsdauer an: ";
                        std::cin>>length;
                        Orte orte(name);
                        ortelist.addOrte(orte);
                        myReiselist[i].setStayId(ortelist.getMySize(),length,myReiselist[i].staySize());
                        myReiselist[i].plusStaySize();
                        added=true;
    

    hab den Fehler gefunden das muss heißen

    ortelist.getMySize()-1
    

    da bei addOrte ja auch die ortelist.mySize schon +1 gemacht wird hab ich quasi immer eine postition zu viel angegeben was aber ja nicht auffällt da die ja alle initialisiert werden 😢


Anmelden zum Antworten