Matrizen einlesen



  • Hallo Leutz,

    einen Code für das einlesen einer Matrix aus einer txt-Datei steht schon bereit.

    #include <algorithm>
    #include <fstream>
    #include <iostream>
    #include <iterator>
    #include <sstream>
    #include <string>
    #include <vector>
    
    using namespace std;
    
    void display(vector<vector<double>> &);
    
    int main(void) {
      ifstream ifs("double.txt");
    
      if (!ifs) {
        cerr << "Datei kann nicht geöffnet werden" << endl;
        exit(-1);
      }
    
      vector<vector<double>> matrix; 
      while (ifs) {
        string line;
        getline(ifs, line);
        istringstream iss(line);
        vector<double> values;
    	istream_iterator<double>(iss);
        copy(istream_iterator<double>(iss),
             istream_iterator<double>(),
             back_insert_iterator<vector<double> >(values));
        if (values.size() > 0) matrix.push_back(values);
      }
    
      display(matrix);
    
      return 0;
    }
    
    void display(vector<vector<double>> &mat) {
    
    	int z = mat.size();
    	int s = mat.at(0).size();
    
    	cout << "Anzahl der Zeilen : " << z << endl;
    	cout << "Anzahl der Spalten: " << s << '\n' << endl;
    
    	for(int i = 0; i < z; ++i) {
    		for(int j = 0; j < s; ++j)
    			cout << mat.at(i).at(j) <<'\t';
    		cout << '\n';
    	}
    }
    

    Wie kann ich diesen Code so modifizieren das ich mehrere Matrizen einlesen und abspeichern kann?

    Einen Auszug aus der txt-Datei:

    =beg=50700 (Element Connectivities)
               20            25           31           32           26
               21            27            2           33           28
               22            28           33           34           29
               23            29           34           35           30
               24            30           35           36           31
               25            31           36            3           32
    =end=
    
    =beg=50800 (Nodal Coordinates)                                        
                1   0.000000E+00   0.100000E+02
                2   0.500000E+02   0.100000E+02
                3   0.500000E+02   0.100000E+03
                4   0.000000E+00   0.100000E+03
                5   0.000000E+00   0.280000E+02
                6   0.000000E+00   0.460000E+02
                7   0.000000E+00   0.640000E+02
                8   0.000000E+00   0.820000E+02
    
    =end=
    

    Vielen Dank im voraus und allen fröhliche Weihnachten :xmas1:

    Ciao



  • Du musst einfach nur ein paar Zeilen gesondert betrachten. Je nach dem, wie kompliziert du es machen willst, kannst du auch flex oder boost spirit verwenden. Ist für einen Zweck, aber mit Kanonen auf Spatzen geschossen.

    Also... Einfach mal testen, ob eine Zeile mit einem "="-Zeichen beginnt. Das sollte schon genügen.



  • Könntest du mir evtl. ein Bsp aus dem Net zeigen.



  • schickano schrieb:

    Könntest du mir evtl. ein Bsp aus dem Net zeigen.

    Wenn du nicht weißt, wie man das erste Zeichen einer Zeichenkette überprüft, dann kann ich dir auch nicht helfen. Dann musst du erstmal die Grundlagen lernen. Und im Internet kannst du bestimmt selber suchen. Das muss ich nicht für dich tun.



  • Beim Einlesen sollte man natürlich immer vorher wissen in welchem Format da was kommt. Erste Frage: wie kann ein Programm erkennen, dass da jetzt eine Matrix folgt. Und zweite Frage: Ist der Zeilenumbruch wirklich die einzige Information aus der man auf die Anzahl der Spalten der Matrix schließen kann?

    Ich hatte hier vor einiger Zeit ein kleines Helferlein namens 'ctest' gepostest; mit dessen Hilfe kann man in einem istream auf ein bestimmtes Zeichen abfragen kann ohne das Zeichen selbst zu lesen. Damit könnte man Deinen Code etwas auf-hübschen:

    #include <algorithm>
    #include <fstream>
    #include <iostream>
    #include <iomanip>
    #include <iterator>
    #include <sstream>
    #include <string>
    #include <vector>
    
    // --   liefert 'true' falls das Zeichen 'e' in 'in' folgt
    template< typename E, typename Traits >
    bool ctest( std::basic_istream< E, Traits >& in, E e )
    {
        if( in.good() )
        {
            const std::ctype< E >& ctype_fac = std::use_facet< std::ctype< E > >( in.getloc() );
            for( Traits::int_type m = in.rdbuf()->sgetc(); ; m = in.rdbuf()->snextc() )
            {
                if( Traits::eq_int_type( m, Traits::eof() ) )
                {
                    in.setstate( std::ios_base::eofbit );
                    break;
                }
                const char c = Traits::to_char_type( m );
                if( c == e )
                {   // --   gesuchtes Zeichen folgt im Stream
                    in.rdbuf()->sbumpc();       // Zeichen konsumieren -> ++Lesezeiger
                    return true;                // ok; Zeichen war da
                }
                if( (in.flags() & std::ios_base::skipws) == 0 || !ctype_fac.is( std::ctype< E >::space, c ) )
                    break;
            }
        }
        return false;
    } 
    
    using namespace std;
    
    void display( vector<vector<double> >& );
    
    int main() {
        ifstream ifs("double.txt");
        if (!ifs) {
            cerr << "Datei kann nicht geöffnet werden" << endl;
            exit(-1);
        }
    
        vector<vector<double> > matrix;
        string tok;
        int no;
        ifs >> setw(5) >> tok >> no; // '=beg=50700 .. '
        ifs.ignore( 999, '\n' ); // Rest der Zeile überlesen
        while (ifs && !ctest( ifs, '=' ) ) { // ctest prüft auf '=' und damit auf '=end='
            string line;
            getline(ifs, line);
            istringstream iss(line);
            vector<double> values;
            copy(istream_iterator<double>(iss),
                istream_iterator<double>(),
                back_insert_iterator<vector<double> >(values));
            matrix.push_back(values);
        }
        ifs.ignore( 999, '\n' ); // '=end= ...' Rest der Zeile überlesen
    
        // hier könnte jetzt die nächste Matrix gelesen werden, aber in der Beispiel-Datei steht da etwas anderes !?
        display(matrix);
    
        return 0;
    }
    

    Stehen die Zahlen 50700 bzw. 50800 für das Format was dann kommt?

    Gruß
    Werner


Anmelden zum Antworten