stringstreams, bei Leerzeichen Zeilenumbruch verhindern



  • Hallo, ich habe ein kleines Problem.
    Ich will aus einer Textdatei, wie z.B. dieser hier: (daten_personen_1)

    Jonathan Tobias;Schulze;
    Gabriel;Meier Müller;
    

    die einzelnen Felder auslesen (getrennt durch ein Semikolon), im Programm weiterverarbeiten und anschließend wieder in dem selben Format in eine andere Datei schreiben. Hier ergibt sich allerdings das Problem, dass ich bei jedem Leerzeichen ein Zeilenumbruch habe, wie folgende Datei zeigt: (daten_personen_2)

    Jonathan
    Tobias;Schulze;
    Gabriel;Meier
    Müller;
    

    Dabei möchte ich nur nach jedem Zeilenumbruch eine neue Zeile haben.
    Die Leerzeichen sollen also wieder Leerzeichen werden.

    Wie könnte ich das verhindern? 😕
    In diesem Code sind für diese Frage wahrscheinlich nur die Funktion

    bool schreibeDatei()
    

    von Zeile 72 bis 104 interessant.

    class person{
      public:
        void setVorname(string & sVar) { sVorname = sVar; }
        void setNachname(string & sVar ) { sNachname = sVar; }
        string getVorname() const { return sVorname; }
        string getNachname() const { return sNachname; }
      private:
        string sVorname;
        string sNachname;
    };
    
    // globaler Personenvektor
    vector <person> g_personenVektor;
    
    string leseDatei()
    {
        string sAusgelesen = "";
        ifstream eingangsdatei("daten_personen_1");
    
        if (!eingangsdatei)
            cout << " wurde nicht gefunden." << endl;
        else
        {
            char c;
            while ( eingangsdatei.get(c) )
                sAusgelesen += c;
    
            if ( !eingangsdatei.eof() )
            {
                cout << "Da stimmt was nicht!" << endl;
                sAusgelesen = "";
            }
    
            eingangsdatei.close();
        }
        return sAusgelesen;
    }
    
    /*
        Benutzt den uebergebenen String um den PersonenVektor mit 
        einzelen Personen zu fuellen
    */
    void fuellePersonenVektor(string & sDatei)
    {
        person einePerson;
        string::size_type i1;         // Position in einem String
        while ( not sDatei.empty() )  // Solange der String nicht leer ist
        {
            i1 = sDatei.find(";");
            if ( i1 > 0 && i1 < sDatei.length() )
            {
                string s(sDatei, 0, i1);
                cout << s << endl;
                einePerson.setVorname(s);
            }
            sDatei.erase(0, i1+1);
    
            i1 = sDatei.find(";");
            if ( i1 > 0 && i1 < sDatei.length() )
            {
                string s(sDatei, 0, i1);
                cout << s << endl;
                einePerson.setNachname(s);
            }
            sDatei.erase(0, i1+1);
    
            g_personenVektor.push_back(einePerson);
        }
    }
    
    /* Schreibt den Inhalt des PersonenVektors in eine Datei */
    bool schreibeDatei()
    {
        ostringstream aout("");
        ofstream ausgangsdatei;
        ausgangsdatei.open("daten_personen_2");
    
        vector<person>::iterator iter = g_personenVektor.begin();
    
        /* Beginn relevanter Teil
        -----------------------------------------------------------------------*/
        while ( iter != g_personenVektor.end() )
        {
            aout << iter->getVorname() << ";"
                 << iter->getNachname() << ";" << endl;
            ++iter;
        }
    
        istringstream ain(aout.str());
    
        string a;
        while(true)
        {
            ain >> a;
    
            if (ain.eof())
                break;
            ausgangsdatei << a << endl;
        }
        /*
        ----------------------------------------------------------------------
        Ende relevanter Teil */
        return true;
    }
    
    int main()
    {
        person einePerson;
        string sDatei = leseDatei(); // komplette Datei wird in einen String gespeichert
        /*  Laengenbegrenzung:
            sDatei.max_size()
    
            F R A G E: Wie koennte man zu groesse Dateien ermitteln, um sie danach aufzuteilen???
        */
        fuellePersonenVektor(sDatei);
        if ( not schreibeDatei() )
            cout << "Schreiben misslungen\n";
        return 0;
    }
    

    Noch ein Hinweis:
    Sämtliche Kombinationen der "endl"-Zeichen von Zeile 85 und 98 habe ich schon ausprobiert und führten nicht zum gewünschten Ergebnis.

    So und nun bin ich mal auf eure Antworten gespannt
    🙂
    und herzlichen Dank schon mal.



  • Erstens: Was hat dieser Beitrag mit Stringstreams zu tun?

    Zweitens: Vielleicht solltest du mal im Debugger verfolgen, wo genau die Newlines sich in deine Namen eingeschmuggelt haben.



  • Vielleicht wird mit diesem Code das Problem ersichtlicher.
    In den ostringstream jeweils ein Wort oder zwei Wörter getrennt durch ein Leerzeichen

    int main()
    {
        ostringstream aout("");
        aout << "Ich weiss" << endl;
        aout << "nicht" << endl;
        aout << "mehr weiter." << endl;
    
        istringstream ain(aout.str());
    
        string u;
        while (1)
        {
            ain >> u;
            if (ain.eof())
                break;
            cout << u << endl;
        }
    }
    

    wobei es dann zu folgender Ausgabe kommt:

    Ich
    weiss
    nicht
    mehr
    weiter.
    

    @CStoll
    1. Was ist das denn sonst, wenn es keine Stringstreams sind?
    2. Debugger hat mir leider nicht weitergeholfen.



  • Erstens: Du hast den Stringstream wirklich gut versteckt 😉 (und nebenbei betrifft dieses Phänomen ALLE IO-Streams - genauer: die istream-Familie)

    Zweitens: operator>> liest bis zum ersten Whitespace (Leerzeichen, Tab, NewLine) ein. Wenn du etwas anderes als Trennzeichen verwenden willst, kannst du getline() verwenden - das liest soweit, bis es das angegebene Endezeichen (Default ist '\n') findet.


Anmelden zum Antworten