Ausgabe eines StrukturArrays schlägt fehl
-
Hallo,
der Gedankengang war, für jede Matrix in eine Struktur zu packen, um die "beliebige Anzahl" zu realisieren. Die Multiplikation habe ich noch nicht beigefügt, da ich erstmal bis hierhin gerne Kritik hätte und meine(n) Fehler korrigieren möchte. Ich habe vorher noch nicht wirklich viel mit Strukturen und StrukturArrays gearbeitet und mache mich jetzt erst über dieses kleine Projekt langsam mit damit vertraut. Bin also über jeden Hinweis dankbar! Folgenden Code habe ich bislang fabriziert:
#include <stdio.h> #include <stdlib.h> /*Beliebige Anzahl Matrizen einlesen, mit beliebigen Zahlen (int, double etc.) initialisieren und dann multiplizieren*/ typedef struct matrix_werte Matrix; struct matrix_werte { unsigned zeile; unsigned spalte; double **werte; }; void cb(); Matrix eingabe(); int ausgabe(unsigned Anzahl, Matrix *Matrizen); int main() { int AnzahlMatrizen = 0; int x = 0; Matrix *Matrizen = NULL; printf("\nAnzahl der Matrizen eingeben: "); scanf("%i",&AnzahlMatrizen); cb(); Matrizen = calloc( AnzahlMatrizen , sizeof(Matrix)); if (Matrizen == NULL) { printf("\nNicht genug Speicher frei!\n"); free(Matrizen); return 0; } for (x = 0 ; x < AnzahlMatrizen ; x++) { printf("\nMatrix Nr. %i\n",x+1); Matrizen[x] = eingabe(); } ausgabe(AnzahlMatrizen, Matrizen); } /*******************************/ /* Funktion um Buffer zu leeren*/ /*******************************/ void cb() { int c=0; while ( (c=getchar() ) != EOF && c != '\n') ; } /*********************************/ /**Eingabe: Zeile, Spalte, Werte**/ /*********************************/ /*********************************/ Matrix eingabe() { int i=0; int y=0; Matrix neu; printf("\nZeilen: "); scanf("%i",&neu.zeile); cb(); printf("\nSpalten: "); scanf("%i",&neu.spalte); cb(); neu.werte = (double**) malloc (neu.zeile * neu.spalte * sizeof(double*) ); for (i=0; i<neu.zeile; i++) { neu.werte[i] = (double*) malloc(neu.spalte * sizeof(double)); if(neu.werte[i]==NULL) { for (i=0; i<neu.zeile; i++) { free(neu.werte[i]); } free(neu.werte); } } printf("Werte bitte zeilenweise eingeben!\n"); for (i=0; i<neu.zeile; i++) { printf("\nZeile %i:",(i+1)); for (y=0; y<neu.spalte; y++) { scanf("%i",&neu.werte[i][y]); } } return neu; } /********************************/ /* Ausgabe Zeile, Spalte, Werte */ /********************************/ int ausgabe(unsigned Anzahl,Matrix *Matrizen) { int i=0; int x=0; int y=0; for (i=0; i<Anzahl; i++) { printf("\nMatrix %i:",(i+1)); printf("\nZeilen: %i",Matrizen[i].zeile); printf("\nSpalten: %i",Matrizen[i].spalte); for(x=0; x<Matrizen[i].zeile; x++) { for(y=0; y<Matrizen[i].spalte; i++) { printf("%lf",Matrizen[i].werte[i][y]); } } } return 0; }
Wenn ich in der Ausgabe die for-Schleife
for(x=0; x<Matrizen[i].zeile; x++) { for(y=0; y<Matrizen[i].spalte; i++) { printf("%lf",Matrizen[i].werte[i][y]); } }
rauskommentiere, klappt alles wunderbar. Wenn nicht, wird einmal der Zeilenwert der ersten Matrix ausgegeben, für die Spalte eine extrem lange Zahl, und dann bricht alles ab. Was ist der Fehler? Vielen Dank im Voraus!
PS:
Bitte beachtet, ich bin Autodidakt und über JEDEN NÜTZLICHEN Hinweis bezüglich des Codes dankbar
-
chmbw schrieb:
Wenn nicht, wird einmal der Zeilenwert der ersten Matrix ausgegeben, für die Spalte eine extrem lange Zahl, und dann bricht alles ab. Was ist der Fehler?
Es gibt keine extrem langen Zahlen in C. Was es gibt, sind Zahlen mit üblicher Länge und Menschen, die vergessen haben, Leerzeichen dazwischen zu platzieren.
-
Du hast die Indexvariablen in der for Schleife und den Arrays verwurschtelt.
-
Big Brother schrieb:
Du hast die Indexvariablen in der for Schleife und den Arrays verwurschtelt.
wieso darf ich das denn nicht bzw. was ist das Problem dabei? Ich änder doch keine Werte.
-
chmbw schrieb:
Wenn ich in der Ausgabe die for-Schleife
for(x=0; x<Matrizen[i].zeile; x++) { for(y=0; y<Matrizen[i].spalte; i++) { printf("%lf",Matrizen[i].werte[i][y]); } }
rauskommentiere, klappt alles wunderbar. Wenn nicht, wird einmal der Zeilenwert der ersten Matrix ausgegeben, für die Spalte eine extrem lange Zahl, und dann bricht alles ab. Was ist der Fehler? Vielen Dank im Voraus!
Wenn du schon sagst das es geht, wenn du diesen Code auskommentierst, dann solltest du ihn erst recht ein paar mal extra durchgucken.
chmbw schrieb:
Big Brother schrieb:
Du hast die Indexvariablen in der for Schleife und den Arrays verwurschtelt.
wieso darf ich das denn nicht bzw. was ist das Problem dabei? Ich änder doch keine Werte.
Und bei so einer Nachricht noch 5 mal durchgucken. Du willst höchstwahrscheinlich nicht i inkrementieren, sondern y.
-
Du sollest für scanf() ein double mit %lf einlesen, und ein unsigned int mit %u. Dann solltest du dafür sorgen, dass der Eingabepuffer nach den scanf()-Aufrufen keine Probleme macht. Wahrscheinlich solltest du auch noch die Rückgabe von scanf() prüfen, um Fehleingaben auszuschliessen.
chmbw schrieb:
wieso darf ich das denn nicht bzw. was ist das Problem dabei? Ich änder doch keine Werte.
Das sag ich dir, wenn vor der Schleife keine Segfaults mehr kommen.
-
Und warum nimmt eingabe() eigentlich beliebig viele Argumente an?
-
Herzlichen Dank für eure schnellen Antworten! die Datentypen und das i / y hätte ich echt selbst finden müssen... *peinlich*
Ich habe jetzt aber alle Datentypen entsprechend, ich krieg beim kompilieren keine warnings etc. mehr. Der Übersicht zuliebe spare ich mir den Code nochmal zu posten.
mngbd schrieb:
Und warum nimmt eingabe() eigentlich beliebig viele Argumente an?
Inwiefern beliebig viele Argumente? Was meinst du genau?
-
chmbw schrieb:
mngbd schrieb:
Und warum nimmt eingabe() eigentlich beliebig viele Argumente an?
Inwiefern beliebig viele Argumente? Was meinst du genau?
Parameterliste fehlt. Wenn in C eine Funktion keine Parameter annimmt, so musst du dies explizit angeben.
-
sprich ich muss schreiben:
eingabe(void)
-
chmbw schrieb:
sprich ich muss schreiben:
eingabe(void)
Ist eine gute Idee.
Den Code kannst du auch nach codepad.org oder so schieben.
-
Danke für den Link! Ich habs mal reinkopiert wie es jetzt grad in meinem Compiler steht:
void habe ich jetzt intuitiv beim aufruf von
eingabe()
weggelassen, was genau erwartet der Compiler denn wenn ichs eintragen würde?!
-
chmbw schrieb:
void habe ich jetzt intuitiv beim aufruf von
eingabe()
weggelassen, was genau erwartet der Compiler denn wenn ichs eintragen würde?!
Wenn nichts zwischen den Klammern steht, dürfen die Argumente beliebig sein. Damit ist der Prototyp nicht sehr aussagekräfig und könnte die Fehlersuche erschweren. Deshalb ist das void nützlich (bei cb() hast du's übersehen).
Mit dem Eingabepuffer ist scheinbar alles in Ordnung, mea culpa.
Wenn man beim Eingaben der Zeilen etwas sagt, was keine Zahl ist, reagiert das Programm unerwartet.
-
wenn ich jetzt in Zeile 49 schreibe:
Matrizen[x] = eingabe(void);
kriege ich folgenden Error:
In function 'main':
Line 49: error: expected expression before 'void'
Line 49: error: too many arguments to function 'eingabe'
-
chmbw schrieb:
wenn ich jetzt in Zeile 49 schreibe:
Matrizen[x] = eingabe(void);
kriege ich folgenden Error:
...Ich meinte vergessen in Zeile 59. Das void muss nur bei Prototypen und Funktions-Definitionen hin, beim Aufrufen nicht.
-
chmbw schrieb:
Line 49: error: too many arguments to function 'eingabe'
Das ist übrigens eine der Fehlermeldungen, die du ohne das void im Prototypen unterdrückt hättest.
-
aaah, wieder was gelernt^^ vielen lieben Dank!
Hier meine aktuelle Version:
mngbd schrieb:
chmbw schrieb:
wieso darf ich das denn nicht bzw. was ist das Problem dabei? Ich änder doch keine Werte.
Das sag ich dir, wenn vor der Schleife keine Segfaults mehr kommen.
was ist jetzt mit meinen Indizes in der for-Schleife?
-
chmbw schrieb:
was ist jetzt mit meinen Indizes in der for-Schleife?
Du hattest y und i verwechselt.
chmbw schrieb:
die Datentypen und das i / y hätte ich echt selbst finden müssen... *peinlich*
Braucht dir nicht peinlich zu sein, sowas schnell zu sehen ist Übungssache. Mir ist es auch nicht aufgefallen.
-
hmm, aber ich kriege nach wie vor nicht die Werte ausgegeben die ich ursprünglich eingegeben habe...
-
chmbw schrieb:
hmm, aber ich kriege nach wie vor nicht die Werte ausgegeben die ich ursprünglich eingegeben habe...
Stimmt, hat bei mir bei einer 2x2-Matrix gerade zweimal die erste Zeile ausgegeben.
Zeile 140:
printf("%lf",Matrizen[i].werte[x][y]); // ^ // hier besser x statt i
Das hilft, solange man keinen Unsinn eingibt:
Anzahl der Matrizen eingeben: 1 Matrix Nr. 1 Zeilen: 2 Spalten: 2 Werte bitte zeilenweise eingeben! Zeile 1:1.0 peter Zeile 2: Matrix 1: Zeilen: 2 Spalten: 21.0000000.0000000.0000000.000000
-
vielen vielen lieben Dank für die schnelle und klasse Hilfe!
Dann mach ich mich jetzt mal an das abfangen von fehlerhaften Eingaben
Gibts nicht einen Befehl womit ich eine Typüberprüfung durchführen kann? Oder muss ich die Eingabe als String einzeln als Zahl zwischen 0 und 9 prüfen?