[GELÖST] Range-For Loop String komisches verhalten (c++11)



  • EDIT: Eigene Dummheit, Auflösung siehe Antworten unten.

    Wenn ich einen Range-For-Loop (C++11) auf einen String anwende erhalte ich ein für mich komisches verhalten:

    bool Tokenizer::operator>>(std::string& line)
    {
        // Reads a line into "line"
        std::cerr << "LINE: " << line << std::endl;
        for (char c : line) {
            std::cerr << "CHAR: " << c << std::endl;
            // ...
        }
    }
    

    Ausgabe:

    LINE: 1+5++6++++
    CHAR: 1
    CHAR: s
    CHAR: t
    CHAR: d
    CHAR: :
    CHAR: :
    CHAR: s
    CHAR: t
    CHAR: r
    CHAR: i

    ich würde jetzt 1 + 5 ... erwarten.
    Wo mache ich meinen Denkfehler?
    MfG



  • Die Range based for Loop sieht OK aus. Bei mir funktioniert alles wie erwartet. Der Fehler steckt wohl woanders. Verändest du vielleicht line in der for Loop? Du hast da mit // ... das da noch mehr in der Schleife steht.



  • Ah ok stimmt in einer verschachtelten Funktion hab ich doch wirklich line geändert.
    line += andererstring.

    Komisch woher dann das std::string kam, weil das tauch nirgends auf (anderer string ist definiert als " " + c).

    Danke 🙂

    Edit: War echt ein dummer Fehler:

    last = " " + c;
    // ...
    line += last;
    

    Gibt selbst mit -pedantic keine Warnung, ist ja valid nur halt großer Bullshit.
    Also line durch tmp ersetzen und + c entweder durch push_back oder std::string(1, c).



  • derFer schrieb:

    Komisch woher dann das std::string kam, weil das tauch nirgends auf (anderer string ist definiert als " " + c).

    Woher der oben gezeigte String kam oder was? Wenn du an line irgendwas anhängst wird irgendwann der von std::string reservierte Platz nicht mehr ausreichen und es wird ein neuer Speicherbereich reserviert und die alten Iteratoren (welche auch die Range based for Loop zum iterieren nutzt) werden ungültig und man kann dort alles mögliche lesen, was nichts mehr mit dem ursprünglichen String zu tun hat. Vielleicht ist auch dein " " + c nicht das was du erwartest, das hängt davon ab was c für einen Typ hat. Wenn c kein std::string ist dann passiert sicher nicht das was du erhoffst.



  • derFer schrieb:

    und + c entweder durch push_back oder std::string(1, c).

    Seit C++14 geht auch:

    last = " "s + c;
    

    Jetzt ist " "s ein std::string und operator+ macht was es soll.



  • sebi707 schrieb:

    Seit C++14 geht auch:

    last = " "s + c;
    

    Jetzt ist " "s ein std::string und operator+ macht was es soll.

    Oh danke, das ist wirklich nützlich 🙂

    Ich hoffe die Compiler führen schnell C++14 Unterstützung ein und die Distributionen steigen endlich mal um.
    (Leider haben viele noch gcc 4.8 das nicht mal C++11 wirklich unterstützt (z.b. regex)).

    (selbes gilt übrigens auch für msvc).


  • Mod

    derFer schrieb:

    Ich hoffe die Compiler führen schnell C++14 Unterstützung ein

    Die sind schon lange fertig!

    und die Distributionen steigen endlich mal um.

    Dies ist dein Problem. Musst du eben selbst tätig werden, wenn deine Distro es nicht tut.



  • SeppJ schrieb:

    Die sind schon lange fertig!

    Naja... https://gcc.gnu.org/onlinedocs/libstdc++/manual/status.html#status.iso.2014
    Bei msvc ist es noch schlimmer da fehlen selbst in der 2015 version c++11 features.

    SeppJ schrieb:

    Dies ist dein Problem. Musst du eben selbst tätig werden, wenn deine Distro es nicht tut.

    Ja das ist schon klar, ich selber habe da keine Probleme, zur Not baue ich mir den GCC selber. Viel mehr sind die Nutzer das Problem auf deren System habe ich ja keinen Zugriff 😉

    Aber das ist ein Anderes Thema, wir kommen schon in den OT rein.
    Danke für die Antworten und noch ein schönes WE,

    Fer


Anmelden zum Antworten