Logikfehler? Klasse



  • Vielen Dank. Ich habe es geändert. Aber das mit der Klammer "}" scheint ein copy-paste Fehler gewesen zu sein...
    Ich habe leider ein Inhaltliches Problem.
    Ich habe den Code gedebuggt und an dieser Stelle bleibt er im Code einfach stehen (RemoveSharp.cpp ->LoadResource):

    while(std::getline(std::cin, temp))
    

    Der Debugger lässt sich nicht weiterschieben und der Fokus geht auf die Console über, wo sich leider nichts tut. Ich kann auch nicht weiterdebuggen...
    Aber die Datei existiert. Ich weiß leider nicht wo mein Fehler steckt.

    PS: Das mit der nbs-Datei hat super funktioniert 👍 🙂

    Gruß Speedy_92



  • Speedy_92 schrieb:

    Vielen Dank. Ich habe es geändert. Aber das mit der Klammer "}" scheint ein copy-paste Fehler gewesen zu sein...
    Ich habe leider ein Inhaltliches Problem.
    Ich habe den Code gedebuggt und an dieser Stelle bleibt er im Code einfach stehen (RemoveSharp.cpp ->LoadResource):

    while(std::getline(std::cin, temp))
    

    Der Debugger lässt sich nicht weiterschieben und der Fokus geht auf die Console über, wo sich leider nichts tut. Ich kann auch nicht weiterdebuggen...
    Aber die Datei existiert. Ich weiß leider nicht wo mein Fehler steckt.

    PS: Das mit der nbs-Datei hat super funktioniert 👍 🙂

    Gruß Speedy_92

    Du willst doch von deinem File lesen, oder?

    Dann sollte das

    while(std::getline(std::cin, temp))
    

    so heißen

    while(std::getline(f, temp))
    

    Gruß
    Tobi



  • Ups... Sry. Kam warscheinlich weil ich mir grad ein Tut über strings noch einmal angeschaut habe, wo grade

    std::getline(std::cin, bla)
    

    erklärt wurde...
    Aber trotzdem danke



  • Tut mir leid, wenn ich nerve 😃
    Aber ich habe jetzt ein Runtime Problem. Es tritt an dieser Stelle auf:

    lines.erase(iter);
    

    in void RemoveSharp::RemoveSharpLines() in der RemoveSharp.cpp.
    Aber in dem vector lines sind alle Zeilen richtig reingeladen worden...

    Folgendes Problem (Kann man hier keine Bilder einfügen?, dann halt der externe Link):klick me



  • Speedy_92 schrieb:

    Tut mir leid, wenn ich nerve 😃
    Aber ich habe jetzt ein Runtime Problem. Es tritt an dieser Stelle auf:

    ahh, ganz übersehener Anfängerfehler:
    Du kannst nicht ohne weiteres innerhalb einer Schleife über eine Liste iterieren und Einträge löschen. Den jedes hinzufügen und löschen kann den Interator ungültig machen! (Dies ist dein Problem).

    Um es verständlicher zu machen, ein Beispiel am Vector. Ein Vector ist ein zusammenhängender Speicherbereich:

    Iteratorposition
                                  |
    Vectorinterner Zeiger ---> [1|2|3|4|5]
    

    Bei jedem Löschen oder Einfügen kann der Speicherbereich des Vektors geändert werden (An eine andere Adresse kopiert und angepasst), zudem ist nicht ganz klar wohin nach einem Löschen - selbst wenn der Speicherbereich identisch bleiben würde - der Iterator zeigen sollte.

    cu André



  • Nimm ein einfaches Prädikat dafür:

    bool startsWithSharp(const std::string& str)
    {
       return str[1] == '#';
    }
    
    void RemoveSharp::RemoveSharpLines()
    {
        lines.erase(std::remove_if(lines.begin(), lines.end(), startsWithSharp));
        ///...
    }
    

    (Soll eigentlich wirklich das zweite Zeichen auf '#' überprüft werden ?
    Das erste Zeichen wäre 'str[0]' !)

    Siehe auch "Effective STL" von Scott Meyers



  • Ja, das 2. Zeichen soll entfernt werden. Und wozu ist der 2. Parameter char c?
    Der ist doch völlig unnötig.
    Tut mir leid, aber was muss ich denn als 3. Parameter angeben in remove_if...
    Ich habe schon in der Referenz geschaut, aber das hat mir nicht weitergeholfen, da du hier startsWithSharp als Parameter angegeben hast, was bei mir nicht funktioniert...

    "RemoveSharp::startsWithSharp": Dem Funktionsaufruf fehlt die Argumentliste. Verwenden Sie "&RemoveSharp::startsWithSharp", um einen Zeiger auf den Member zu erstellen.
    

    Weil ich wüsste auch ehrlich gesagt nicht, was ich bei startsWithSharp als Parameter angeben muss, weil ich kann ja lines nicht durchiterieren...



  • *push* 😃



  • Ein Funktionsobjekt, oder eine Funktion.

    Hier auch mit einem Beispiel:

    http://www.cplusplus.com/reference/algorithm/remove_if.html

    Für Funktionsobjekt google mal nach Funktor/Funktionsobjekt.



  • Ich habe in einem Tutorial folgenden Satz als Definition eines Functors gesehn:

    Funktionsobjekte sind Objekte, deren Klasse den Operator () überlädt. Nachfolgend ist ein Beispiel für einen solchen Functor aufgeführt. Er soll dazu dienen, die Werte der Elemente in einem Container zu begrenzen.
    

    Allerdings sehe ich in dem remove_if-Beispiel nichts von Operatorüberladung... oder bin ich etwa blind?

    In dem Wikipedia-Artikel wird die Operator-Überladung wiederum bestätigt:

    Bei Funktionsobjekten oder Funktoren handelt es sich um Objekte, die genauso aufgerufen werden können wie Funktionen. Bei ihnen ist der Funktionsoperator () mit der Operatorfunktion „operator()“ überladen. Es sind Objekte, die sich wie Funktionen verhalten, aber trotzdem alle Eigenschaften von Objekten haben. Bei den Funktionsobjekten gibt es folgende Kategorien:
    
        * Generatoren ohne Funktionsparameter „f()“
        * Unäre Funktionen mit einem Funktionsparameter „f(x)“
        * Binäre Funktionen mit zwei Funktionsparametern „f(x,y)“
    

    Deswegen habe ich es noch nicht verstanden, da die beiden Beispiele unterschiedlich sind und (für mich) keine Gemeinsamkeiten in Sachen Functor haben.



  • Hallo,

    Speedy_92 schrieb:

    Allerdings sehe ich in dem remove_if-Beispiel nichts von Operatorüberladung...

    Da wird auch kein Funktor eingesetzt, sondern ein(e) (Zeiger auf eine) globale Funktion, die/der ebenfalls als Argument für remove_if verwendet werden darf. Also stimmt schon, was drakon geschrieben hat:

    drakon schrieb:

    Ein Funktionsobjekt, oder eine Funktion.

    MfG,

    Probe-Nutzer



  • Hallo,
    ich habe gerade ein wenig im Forum gestöbert und eine viel einfachere Methode gefunden, um ein Element aus einem std::vector zu löschen. Hier ein kleines ungetestetes Beispiel:

    std::vector<int> my_vec;
    
    my_vec.push_back(1);
    my_vec.push_back(2);
    my_vec.push_back(3);
    my_vec.push_back(4);
    my_vec.push_back(5);
    
    std::vector<int>::iterator iter = my_vec.begin();
    while(iter != my_vec.end())
    {
        if((*iter) == 4)
            iter = my_vec.erase(iter);
        else
            iter++;
    }
    

    Weil erase einen Iterator auf das nachfolgende Element angibt.



  • Speedy_92 schrieb:

    Hallo,
    ich habe gerade ein wenig im Forum gestöbert und eine viel einfachere Methode gefunden, um ein Element aus einem std::vector zu löschen. Hier ein kleines

    Ja. Das wird so auch viel gemacht, jedeoch ist das nicht sehr elegant. Die Methode über Funktionsobjekte/Funktionen ist dem eigentlich zu bevorzugen, aber schlussendlich deine Entscheidung. 😉


  • Mod

    drakon schrieb:

    Speedy_92 schrieb:

    Hallo,
    ich habe gerade ein wenig im Forum gestöbert und eine viel einfachere Methode gefunden, um ein Element aus einem std::vector zu löschen. Hier ein kleines

    Ja. Das wird so auch viel gemacht, jedeoch ist das nicht sehr elegant. Die Methode über Funktionsobjekte/Funktionen ist dem eigentlich zu bevorzugen, aber schlussendlich deine Entscheidung. 😉

    Es ist nicht nur nicht elegant, es ist auch ineffizient. Da die Komplexität eines einzelnen erase jeweils linear bzgl. der Distanz zum Ende des vectors ist, hat man im schlimmsten Fall eine quadratische Komplexität für den gesamten Vorgang. remove_if und das folgende erase haben aber jeweils nur lineare Komplexität.


Anmelden zum Antworten