Verhalten von Stringstream



  • Hi zusammen

    hm.. irgendwie schein ich das mit den stream offensichtlich noch nicht verstanden haben. Zumindest funktioniert der stringstream nicht so, wie ich es vermutet hätte .. !?!

    äh jo, das heisst konkret:

    std::stringstream ssTest(std::stringstream::in | std::stringstream::out);
    std::string sTest;
    ssTest << "aa";
    ssTest << "bb";
    ssTest >> sTest;
    OutputDebugString(sTest.c_str());
    ssTest >> sTest;
    OutputDebugString(sTest.c_str());
    

    Dieser Code müsste für mich zuerst "aabb" schreiben und dann "". Zuerst wird aa in den stream geschrieben. Dann wird bb in den stream geschrieben. Dann wird aabb auf dem stream entfernt und in sTest geschrieben. Dann musste der stream eof ein und somit "" zurückgeben.

    Naja, so hätte ich es erwartet. Effektiv ist die Ausgabe "aabb" und "aabb".

    Folgend ein zweites Beispiel:

    std::stringstream ssTest(std::stringstream::in | std::stringstream::out);
    std::string sTest;
    ssTest << "aa";
    ssTest >> sTest;
    OutputDebugString(sTest.c_str());
    ssTest << "bb";
    ssTest >> sTest;
    OutputDebugString(sTest.c_str());
    

    Diess Beispiel musste jetzt nach meiner Theorie 🙂 zuerst "aa" ausgeben und dann "bb". Effektiv ist die Ausgabe zuerst "aa" und dann nochmal "aa". bb wird ganz ignoriert!?

    hm.. ich bin jetzt etwas verwirrt.. hat jemand eine idee, welche Denkfehler ich mache?

    Danke für eure Bemühungen! Grüsse, Dominic



  • der Stringstream enthält nach dem ersten >> tatsächlich "".

    aber beim zweiten wird dein String nicht überschrieben!
    stattdessen wird an dein "aabb" ein "" angehängt!



  • wenn das einlesen fehlschlägt, dann verändert operator>> dasjenige objekt, in das eingelesen werden soll nicht.

    das einlesen schlägt z.b. dann fehl, wenn das ende des strings erreicht wird (!).

    zum veranschaulichen: setze nach jedem DebugOutput... sTest wieder auf "".

    /edit: mit ssTest.clear() kannst du dem stringstream zurücksetzen, sodass beispiel 2 funktioniert. beispiel 1 wird so nicht funktionieren, weil nichts mehr im stringstream drin ist, und die einleseoperation daher immer fehlschlägt.

    @DrakoXP: Nö 🙂



  • naja, so ganz verstanden hab ichs noch nicht aber bin es am studieren. Kann ich nicht mehr in in strea hineinschreiben hineinschreiben, sobald ich einmal eof erreicht habe, hab ich das richtig verstanden?

    gibt es denn eine Möglichkeit einen stringstream auf diese Weise zu verwenden oder ist das so absurt? Oder gibt es evtl. eine andere klassen in der standard-library, die für meine Zwecke besser geeignet wären?

    Merci für eure Antworten, das gibt mir auf den Fall mal einen Ansatz!



  • Hm, das könnte vielleicht eine Lösung sein für mich. Das sollte keine Nebeneffekte haben abgesehen davon, dass der Zeigen von ssTest ändert und alle gelesenen Daten .. oder ?

    std::stringstream* ssTest = new std::stringstream();
    std::string sTest;
    *ssTest << "aa";
    *ssTest >> sTest;
    OutputDebugString(sTest.c_str());
    if (ssTest->eof())
    {
    	delete(ssTest);
    	std::stringstream* ssTest = new std::stringstream();
    }
    sTest = "";
    *ssTest << "bb";
    *ssTest >> sTest;
    OutputDebugString(sTest.c_str());
    

    thanx und gruss, dominic



  • naja, kommt darauf an, was du machen willst. im einfachsten fall, so etwas:

    {
      stringstream tmp;
      string str;
      tmp << "aa"; //oder gleich: stringstream tmp("aa");
      tmp >> str;
    
      Output(str);
    }
    {
      stringstream tmp;
      string str;
      tmp << "bb"; //oder gleich: stringstream tmp("bb");
      tmp >> two;
    
      Output(str);
    }
    

    aber diesem beispiel fehlt jederlei realitätsbezug.
    nur: hier mit zeigern herumzufrickeln ist mit sicherheit *nicht* die lösung.

    anm.:
    wenn du siehst: if (str.eof()) , dann verwende doch str.clear() , anstatt einen völlig neuen stringstream anzulegen (das war die intention des vorigen postings).

    du solltest übrigens jedes mal, wenn du aus einem stream einliest, überprüfen, ob das einlesen geklappt hat. und zwar so:

    int i;
    if (ss >> i)
    {
      //einlesen hat geklappt...
    }
    else //hat nicht geklappt-
    {
       ss.clear(); 
       //lies auf eine andere art und weise ein.
    }
    

Anmelden zum Antworten