Matrix aus Datei einlesen volldynamisch mehrdimensional
-
Hallo an alle,
da ich hier neu bin, erst mal n wenig zu mir - ich bin 'n recht frischer Informatikstudent
und seit neuestem auf nem C Trip - in der Uni bieten se nur JavaGenug der Worte nun zum Problem:
Ich würde gerne eine Matrix aus einer Datei einlesen, dabei können die Dimensionen
der Matrix von Datei zu Datei variieren.
Um die Matrixgrösse anzupassen hab ich mir mal das folgende Codeschnipsel geschrieben - läuft merkwürdigerweise nur in einem von 3 Compilern.
Die Frage wär nun, was soll ich anders/besser machen#include <stdio.h> #include <iostream.h> #include <stdlib.h> struct x { int a; char *b; }; main() { struct x z; z.a = 10; z.b = "test"; cout << z.a; cout << z.b; cout << "\n"; //Array int zeile = 4; int spalte =4; int i; struct x ** matrix; //Speicher zuweisen Zeilen matrix = (struct x **)malloc(zeile * sizeof(struct x)); //Speicher für Spalten zuweisen i = 0; for ( i;i<zeile;i++) { matrix[i] = (struct x *)malloc(spalte * sizeof(struct x)); } // Matrix mit Werten belegen for (int l=0;l<4;l++) { struct x g[l]; if(l==1) g[l].b = "Erster Wert"; else g[l].b = "Zweiter Wert"; matrix[l][l] = g[l]; cout << l << ". Lauf \n"; //Kontrollausgabe } struct x t; for (int w=0;w<4;w++) { t = matrix[w][w]; cout << t.b << "\n"; } // (realloc) Dynamische Erweiterung der Matrix // Neue Grösse zeile = 5; spalte = 5; matrix = (struct x **)realloc(matrix,zeile * sizeof(struct x)); cout << "--------------------------\n"; // Kontrollausgabe for (int v=0;v<zeile;v++) { cout << "--------------" << v << "------------ \n"; // Kontrollausgabe matrix[v] = (struct x *)realloc(matrix[v],spalte * sizeof(struct x)); } cout << "\nAusgabe nach Erweiterung\n\n"; //Testwerte einfüllen for (int l=0;l<5;l++) { struct x g[l]; g[l].b = "RR"; matrix[0][l] = g[l]; } matrix[4][4] = z; //Testwerte Ausgeben for (int w=0;w<5;w++) { cout << w << ". Wert : "; t = matrix[w][w]; cout << t.b << "\n"; } system("pause"); }
Und ist das überhaupt eine gute Idee das so zu machen - wie könnte man das anders machen?
Vorallem bei Zeile 45 bin ich mir recht unsicher, wie bekomme ich denn das schön
dynamisch gebacken? (Erzeugen von x char Speicherplätzen, die nicht löschen und
ihren Anfang ins Array speichern)EDIT: Ok die structs auserhalb der Schleifen zu deklarieren und ohne Variable hat schon mal geholfen, es läuft nun überall...
Wenn ich zeile 85 allerdings auskommentiere, dan wirft mir borland einen Fehler
- Speicherzugrifsverletzung - ich denk mal, weil dann ein Wert gefragt wird, der nicht gesetzt wurde, andere Compiler geben da dann halt Müll zurück -
Wie kann ich denn das elegant lösen?MfG
-
Hallo,
ich weiss zwar nicht, was du mit deinem Programm bewirken moechtest, aber ich
habe da mal ein paar Zeilen geaendert. Unter Linux kompiliert und laeuft as Programm so mit g++:[b]#include <iostream> //Die Klasse heisst nun so[/b] [b]#include <string.h> //wird fuer memset benoetigt[/b] [b]using namespace std; //sonst gibt es kein cout [/b] struct x { int a; char *b; }; struct x ** resize_matrix (struct x ** matrix, int old_z, int old_s, int new_z, int new_s) { [b]matrix = (struct x **)realloc(matrix, new_z * sizeof(struct x *)); //Hier hattest du einen Fehler[/b] cout << "--------------------------" << endl; // Kontrollausgabe for (int v=0; v<new_z; ++v) { cout << "--------------" << v << "------------ " << endl; // Kontrollausgabe matrix[v] = (struct x *)realloc(matrix[v], new_s * sizeof(struct x)); [b]if (v>=old_z) memset(matrix[v], 0x0, new_s * sizeof(struct x));[/b] [b]else memset(matrix[v]+old_s, 0x0, (new_s-old_s) * sizeof(struct x));[/b] } return matrix; } int main(void) { struct x z; z.a = 10; z.b = "test"; cout << z.a << " " << z.b << endl; //Array int zeile = 4; int spalte = 4; int i; struct x ** matrix; //Speicher zuweisen Zeilen [b]matrix = (struct x **) malloc(zeile * sizeof(struct x *)); //Hier hattest du einen Fehler[/b] //Speicher für Spalten zuweisen for (i=0; i<zeile; ++i) { matrix[i] = (struct x *) malloc(spalte * sizeof(struct x)); [b]memset(matrix[i], 0x0, spalte * sizeof(struct x)); // Speicher, der mit malloc alloziert wurde, sollte initialisiert werden[/b] } // Matrix mit Werten belegen for (int l=0; l<4; ++l) { if (l == 1) matrix[l][l].b = "Erster Wert"; [b]//das scheint zu klappen, ob das richtig ist, weiss ich nicht [/b] else matrix[l][l].b = "Zweiter Wert"; [b] // dito [/b] cout << l << ". Lauf " << endl; //Kontrollausgabe } struct x t; for (int w=0; w<4; ++w) { t = matrix[w][w]; cout << t.b << endl; } // (realloc) Dynamische Erweiterung der Matrix // Neue Grösse [b]matrix = resize_matrix(matrix, 4, 4, 5, 5); //Laengere Programmteile in Funktionen auslagern[/b] cout << "\nAusgabe nach Erweiterung\n\n"; //Testwerte einfüllen for (int l=0; l<5; ++l) matrix[0][l].b = "RR"; matrix[4][4] = z; //Testwerte Ausgeben for (int w=0; w<5; ++w) cout << w << ". Wert : " << matrix[w][w].b << endl; return 0; }
Da ich nicht so recht weiss, was du eigentlich mit machen moechtest, kann ich
nichts weiter zu sagen. Vielleicht nur noch eins: mir gefaellt es nicht.Da ich eher in C statt in C++ bewandert bin, kann es sehr gut sein, dass ich
Fehler uebersehen habe.Was meinst du mit volldynamisch und mit mehrdimensional?
Viel Spass damit
mcr
-
Ach uebrigens,
was du hier schreibst ist kein reiner C-Code, sondern eher C++.
Gehoert also nicht hier hin.Gruss mcr
-
mcr schrieb:
Ach uebrigens,
was du hier schreibst ist kein reiner C-Code, sondern eher C++.
Gehoert also nicht hier hin.Gruss mcr
Bis auf das cout ist der Code aber sehr C-isch. Der OP darf selbst entscheiden, ob der diese durch printf()s ersetzt oder ob ich ihn zu den C++-Leuten verschiebe, die ihm sicher std::vector und ähnliches um den Latz knallen werden
-
Hi,
danke erst mal für deine Mühe
Immerhin war ich nah dran...
Das mit dem initialisieren is gut, wusst nicht wie das geht...
Ok, das cout wird gestrichenSoll eigentlich reiner C Code sein!!
Witziger Weise hats der Borlandcompiler trotz angehaktem C verstanden...Das Ziel vom Ganzen soll sein, 2 oder mehr Textdateien ein zu lesen, welche
Matrixform haben, dabei kann aber auch so was auftreten
->...23 44 47
...34 34... <- Lücke
34 34 -6..3Und diese dann eben bequem zu verarbeiten, dachte mir Arrays sint da ganz nützlich.
Das abenteuerliche Struct Konstrukt kommt daher, das ich mir nicht Helfen konnte
als es darum ging char Werte vernünftig im Array zu Lagern, ich weis ja nicht
wie gross die Zahlen werden...MfG
-
Hallo,
ok, man muesste noch ein zwei stellen weiter aendern, damit da dann ansi c draus wird.
1. iostream gibt es in es nicht, da heisst es dann stdio.h
2. Variablen muessen am Anfang eines Blockes deklariert werden (ok, nach dem neuen Standard nicht)
3. // ist kein gueltiges Kommentarzeichen. Hier verwendet man /* */Bei Zuweisungen wie z.b = "test" bin ich mir nicht sicher. Ich haette
ausreichend Speicher mit malloc alloziert und dann sprintf oder memcpy
gemacht.Das mit den Luecken habe ich nicht so ganz verstanden.
Wenn du die Moeglichkeit hast auf die Gestaltung der Dateien Einfluss zu nehmen, wuerde ich vorschlagen, du gibst ein Format fuer diese vor. So z.B.:1.Zeile: Anzahl Zeilen Anzahl Spalten
jede weitere Zeile: immer Anzahl Spalten viele ZahlenDadurch waere das Einlesen deutlich leichter gemacht und kannst dich dann deiner eigentlichen Aufgabe widmen.
Hier noch mal mein Code nach Ansi C konvertiert:
#include <stdio.h> #include <stdlib.h> #include <malloc.h> #include <string.h> struct x { int a; char *b; }; struct x ** resize_matrix (struct x ** matrix, int old_z, int old_s, int new_z, int new_s) { int v; matrix = (struct x **)realloc(matrix, new_z * sizeof(struct x *)); printf("--------------------------\n"); for (v=0; v<new_z; ++v) { printf("--------------%d------------\n", v); matrix[v] = (struct x *)realloc(matrix[v], new_s * sizeof(struct x)); if (v>=old_z) memset(matrix[v], 0x0, new_s * sizeof(struct x)); else memset(matrix[v]+old_s, 0x0, (new_s-old_s) * sizeof(struct x)); } return matrix; } int main(void) { struct x ** matrix; struct x z; int zeile = 4; int spalte = 4; int i; z.a = 10; z.b = "test"; printf("%d %s\n", z.a, z.b); /* Speicher zuweisen Zeilen */ matrix = (struct x **) malloc(zeile * sizeof(struct x *)); /* Speicher für Spalten zuweisen */ for (i=0; i<zeile; ++i) { matrix[i] = (struct x *) malloc(spalte * sizeof(struct x)); memset(matrix[i], 0x0, spalte * sizeof(struct x)); } /* Matrix mit Werten belegen */ for (i=0; i<4; ++i) { if (i == 1) matrix[i][i].b = "Erster Wert"; else matrix[i][i].b = "Zweiter Wert"; printf("%d.Lauf\n", i); } for (i=0; i<4; ++i) printf("%s\n", matrix[i][i].b); /* (realloc) Dynamische Erweiterung der Matrix */ /* Neue Grösse */ matrix = resize_matrix(matrix, 4, 4, 5, 5); printf("\nAusgabe nach Erweiterung\n\n"); /* Testwerte einfüllen */ for (i=0; i<5; ++i) matrix[0][i].b = "RR"; matrix[4][4] = z; /* Testwerte Ausgeben */ for (i=0;i<5;++i) printf("%d. Wert : %s\n", i, matrix[i][i].b); return 0; }
-
Hi,
ich denke du hast Recht, ich werde mich vorerst mit einer vorgegebenen Formatierung
der Textfiles zufrieden geben
Und danke nochmals für das Umstricken meines Codes...MfG,
RZ