Problem mit vector push_back



  • Hallo,

    mein Problem ist folgendes:

    Ich habe eine Datei mit zwei Spalten und Leerzeilen zwischen den jeweiligen Datensaetzen in etwa wie:

    1 x
    2 y
    3 z
    
    1 p
    2 r
    3 s
    
    [latex]\vdots \quad\vdots [/latex]
    

    Ich moechte es in die Form bringen:

    1 x p ...
    2 y r ...
    3 z s ...
    

    Die Werte sind in einem zweidimensionalen vector gespeichert. Mein erster Ansatz war mittels push_back einfach die gewollten Elemente hinten an jedes Element des Zielvektors einzufuegen. Das ging gruendlich schief. Deshalb nun meine Frage:

    Hat jemand eine Idee, wie ich mein Vorhaben umsetzen koennte?

    Vielen vielen Dank fuer Eure Hilfe.



  • Benutz ein map<string, vector<char> >
    key ist Deine 1. Spalte (1, 2, 3 etc.), und die Werte (Buchstaben) packst Du als Wert in den entsprechenden vector.



  • Danke fuer Deine Antwort. Wie genau meinst Du das? Habe noch nie mit C++ maps gearbeitet und was ich versucht habe, mag der Compiler nich:

    for(i = 1; i <= NKPOINTS; i++){
        map<i,dat_res[i-1]>;
      }
    

    Wie greife ich mit Maps eigentlich auf den vector zu, in dem ich die Daten gespeichert habe?

    Kommt key anstelle von string in map<string, vector<char> > ? Kannst Du mir ne gute Referenz empfehlen, wo ich auch Beispiele finde? Denn, wie Du sicherlich gemerkt hast: Ich habe keine Ahnung.

    Danke



  • Gute Referenz gibt es hier:
    http://www.cppreference.com/



  • und schau mal auf diese Seite der Thread von grizzel.



  • @Braunstein: auf welche Seite?



  • lies mal genau;)

    auf DIESER seite den thread : http://www.c-plusplus.net/forum/viewtopic-var-t-is-210460.html



  • @drakon: Danke, mal schauen, ob es mir weiterhilft



  • Hallo Borninger,

    wenn tatsächlich immer nur 1,2,3 in der ersten Spalte steht, so benötigst Du keine map, sondern kannst die Tabelle auch in ein Array von drei vectoren einlesen. Baue Dir dazu am besten eine Struktur, die einer Einheit aus zwei Spalten entspricht. Da 1,2,3 vorne immer gleich ist, braucht man sich nur die drei Texte zu merken - ich nehme mal an, es sind Texte und nicht nur einzelne Zeichen. Der folgende Code funktioniert aber auch mit einzelnen Zeichen.

    #include <string>
    #include <iostream>
    #include <vector>  // brauchen wir später für 'alles'
    #include <fstream> // ifstream, ofstream
    #include <algorithm> // copy
    #include <iterator> // ostream_iterator
    
    struct Tupel
    {
        enum { size = 3 };
        std::string m_txt[size]; // die 2.Spalte mit 'size' Zeilen
    };
    
    // --   list:
    //  1 Text
    //  2 mehr-Text
    //  3 noch-mehr-Text
    //  .. usw. bis Tupel::size
    std::istream& operator>>( std::istream& in, Tupel& tp )
    {
        int nr;
        for( int idx = 0; idx < Tupel::size && in >> nr >> tp.m_txt[idx]; ++idx  )
            if( nr != idx + 1 )
                in.setstate( std::ios_base::failbit );
        return in;
    }
    

    So ein Tupel liest genau einmal drei Zeilen mit 1,2,3 und zwei Spalten ein.

    Für die ganze Tabelle deren Spaltenanzahl beliebig sein kann, reicht dann ein (bzw. ein Array von 3) vector'en.

    int main()
    {
        using namespace std;
        vector< string > alles[Tupel::size];    // die Tabelle
    
        // --   Einlesen
        ifstream file("input.txt");
        if( !file.is_open() )
            cerr << "Fehler beim Oeffnen der Datei" << endl;
        for( Tupel trp; file >> trp; ) // bis Fehler oder Ende
        {
            for( int i= 0; i < Tupel::size; ++i )
                alles[i].push_back( trp.m_txt[i] );
        }
        if( !file.eof() ) // prüfen, ob Fileende erreicht
            cerr << "fehler beim Lesen" << endl;
    
        // --   Ausgeben
        ofstream ausgabe("output.txt");
        for( int i = 0; i < Tupel::size; ++i )
        {
            copy( alles[i].begin(), alles[i].end(),
                ostream_iterator< string >( ausgabe << i+1 << " ", " " ) );
            ausgabe << endl;
        }
        return 0;
    }
    

    Gruß
    Werner


Anmelden zum Antworten