Problem bei Kombination struct, Pointer/Referenz und Funktion



  • Hallo,

    ich bin ein Neuling auf dem Gebiet von C++ (oder eigentlich sogar generell des Programmierens). Ich versuche gerade ein bestehendes lineares Programm mittels C++ heuristisch zu lösen.
    Dazu möchte ich im ersten Schritt meine Parameter und Variablen (Daten für Vektoren, Matrizen, int,…) in einem struct abspeichern. (Damit ich in den folgenden Funktionen nur jeweils eine Referenz/Pointer übergeben muss.
    Zusammengefasst würde ich gerne Vektoren/Matrizen aus einer .txt-Datei einlesen, in einem struct abspeichern, sodass sie in anderen Funktion verwendet werden können.

    Im folgenden Beispiel sollten die Daten der Vektoren auch außerhalb der Funktionen ausgegeben werden können (global), dabei entsteht mir jedoch ein Fehler bezüglich Index out of range. Ich tue mir in diesem Fall etwas schwer bei der Kombination aus Pointer, Referenzen, structs und Funktionen. Separat betrachtet verstehe ich diese Themengebiete jedoch schon halbwegs.

    Folgend bei Code:

    #include<iostream>
    #include<vector>
    #include<algorithm>
    #include<fstream>
    #include<string>
    
    using namespace std;
    
    struct myStruct{
    	vector<vector<int>> matrix;
    	vector<int> vector;
    };
    
    void readData(myStruct *production);
    void readData2(myStruct *production);
    
    int main(){
    
    	myStruct production;
    	vector<vector<myStruct>> **matrices;
    	vector<myStruct> *vec;
    
    	readData(&production);
    	readData2(&production);
    
    	//Wenn ich die Ausgabe auf folgende Weise versuche, bekomme ich 
    	//einen Fehler mit Index out of range...
    	/*	
    	for(int l=0; l < 5; l++){
    		for( int k=0; k < 5; k++){
    			cout << production.matrix[l][k] << "\t";
    			}
    			cout << endl;
    	}
    
    	for (int k=0; k < 5; k++){
    		cout << production.vector[k] << " ";
    	}*/
    
    	getchar();
    	getchar();
    	return EXIT_SUCCESS;
    }
    
    void readData(myStruct * production){
    	ifstream in("Matrix2D.txt");
    	myStruct r;
    
    	if(in.fail()){
    			cout << "Fehler beim oeffnen von Matrix2D.txt";
    			exit(0);
    	}
    	for (int l=0; l < 5; l++){
    		vector<int> row;
    
    		//1-4
    		for (int k=0; k < 5; k++){
    			int input=0;
    			in >> input;
    			row.push_back(input);
    		}
    		r.matrix.push_back(row);
    	}
    	for(int l=0; l < 5; l++){
    		for( int k=0; k < 5; k++){
    			cout << r.matrix[l][k] << "\t";
    			}
    			cout << endl;
    		}
    	cout << endl;
    }
    
    void readData2(myStruct * production){
    	ifstream in("vector1D.txt");
    	myStruct r;
    
    	if(in.fail()){
    			cout << "Fehler beim oeffnen von vector1D.txt";
    			exit(0);
    	}
    	for (int l=0; l < 5; l++){
    			int input=0;
    			in >> input;
    			r.vector.push_back(input);
    		}
    	for (int k=0; k < 5; k++){
    
    		cout << r.vector[k] << "\t";
    	}
    }
    

    Text-Datei (Matrix2D.txt)
    1 2 3 4 5
    2 4 6 8 10
    1 3 5 7 9
    5 6 7 8 9
    2 3 4 5 6

    Text-Datei(vector1D.txt)
    2 4 6 8 10

    (Hätte ich auch in eine Datei zusammenführen können, wollte es jedoch versuchsweise trennen)

    Vielleicht könnt ihr mir bitte weiterhelfen, auch wenn ich möglicherweise banale Fehler gemacht habe!

    Vielen Dank,
    Grüße PaX



  • Du übergibst zwar einen Zeiger production an die read-Funktionen, aber du verwendest ihn dort nie. Wie soll also ein Wert drin stehen?
    Im Übrigen kennt ein vector seine Grösse, du soltest also nie eine Konstante benutzen, um in einer for-Schleife auf die Werte zuzugreifen.



  • Hallo Manni,

    danke für deinen Hinweis. Eigentlich klar im Nachhinein 🙂
    Ich habe es jetzt noch einmal überarbeitet und es macht nun das was es soll...

    Folgend nun die vorläufige Lösung:

    struct myStruct{
    	vector<vector<int>> matrix;
    	vector<int> vector;
    };
    
    void readData(myStruct *production);
    void readData2(myStruct *production);
    
    int main(){
    
    	myStruct production;
    	vector<vector<myStruct>> **matrices;
    	vector<myStruct> *vec;
    
    	readData(&production);
    	readData2(&production);
    
    	for(int l=0; l < production.matrix.size(); l++){
    		for( int k=0; k < production.matrix.size(); k++){
    			cout << production.matrix[l][k] << "\t";
    			}
    			cout << endl;
    	}
    
    	cout << endl;
    
    	for (int k=0; k < production.vector.size(); k++/*int k=0; k < 5 ; k++*/){
    		cout << production.vector[k] << "\t";
    	}
    
    	getchar();
    	getchar();
    	return EXIT_SUCCESS;
    }
    
    void readData(myStruct * production){
    	ifstream in("Matrix2D.txt");
    
    	if(in.fail()){
    			cout << "Fehler beim oeffnen von Matrix2D.txt";
    			exit(0);
    	}
    	for (int l=0; l < 5; l++){
    		vector<int> row;
    
    		//1-4
    		for (int k=0; k < 5; k++){
    			int input=0;
    			in >> input;
    			row.push_back(input);
    		}
    		(*production).matrix.push_back(row);
    	}
    }
    
    void readData2(myStruct * production){
    	ifstream in("vector1D.txt");
    
    	if(in.fail()){
    			cout << "Fehler beim oeffnen von vector1D.txt";
    			exit(0);
    	}
    	for (int l=0; l < 5; l++){
    			int input=0;
    			in >> input;
    			(*production).vector.push_back(input);
    		}
    }
    

    Grüße
    PaX



  • Und wieder das verflixte 2D-Array Problem 😉
    Du benutzt einen std::vector<std::vector<int>> für die Darstellung, was etwas umständlich zu handhaben ist. Wenn du eine rechteckige Matrix hast kannst du einen einfachen std::vector<int> benutzen, musst allerdings die Indizes von 2D nach linear selbst umrechnen. Lässt sich super in eine eigene Klasse verpacken und ist eine schöne Anfängeraufgabe.

    Außerdem übergibst du die Parameter an die readdata Funktionen als Zeiger, ich fände Referenzen dort besser. Und wo wir gerade dabei sind, readdata und readdata2 sind etwas unglücklich implementiert. Erstens haben sie keine aussagekräftige Namen und zweitens könnte man sowas etwas geschickter programmieren:

    std::vector<int> read_data_vector( const std::string& FileName )
    {
       std::vector<int> v;
    
       // lese Daten
       // ...
    
       return v;
    }
    
    Array2D read_matrix_data( const std::string& FileName )
    {
       Array2D a;
    
       // lese Daten
       // ...
       return a;
    }
    

    Und wenn du das Datenformat selbst festlegen kannst könnte man sogar die Stream Operatoren überschreiben, um das an die STL Standards anzulehnen.



  • Hallo DocShoe,

    vielen Dank für deine Hinweise. Im ersten Schritt war ich anfangs nur froh, dass es das gemacht hat was es soll. Jetzt werde ich versuchen deine Tipps zu berücksichtigen.

    Also danke nochmals!


Anmelden zum Antworten