Zeilen und Spaltenweise einlesen und als Bruch darstellen(Zweidimensionales Array)


#1
Hallo zusammen,
ich stehe erneut vor einem Problem. Undzwar soll ich ein Spiel Namens Domino erstellen, der die Felder des Arrays mit den gleichen Augenzahlen aneinander legen und als Bruch darstellen soll.
Zuerst wollte ich mal das einlesen thematisieren. Dies soll über eine zusätzliche Funktion Namens "einlesen" passieren.

Das Problem hierbei ist, dass nach 7 Zeilen Iteration, ich immer noch etwas eingeben kann obwohl ja nach 7 Zeilen die Schleife aufhören soll.
Vielleicht kann mir jemand dabei helfen auch die Ausgabe als Bruch vorerst darzustellen, ohne die Sortierung.

C:
#include <stdio.h>
#include <math.h>
#include <stdlib.h>

int Steine[7][2];
int i_zeile, i_spalte, k;
    
main(){
    printf("Bitte geben Sie nun 7 Dominosteine ein\n");
    einlesen();
    for(k = 0; k < 7; k++)printf("%d. %d\n", (k+1) ,Steine[k][k]); /*Hier soll die Ausgabe als Bruch dargestellt werden*/
}

einlesen(){
    /*Einlesen der Zahlen, Zeilen- und Spaltenweise*/
    for(i_zeile = 0; i_zeile < 7; i_zeile){
        for(i_spalte = 0; i_spalte < 2; i_spalte){
            scanf("%d", &Steine[i_zeile][i_spalte]);
        }
    }
    
}
 

cwriter

Erfahrenes Mitglied
#2
Das Problem hierbei ist, dass nach 7 Zeilen Iteration, ich immer noch etwas eingeben kann obwohl ja nach 7 Zeilen die Schleife aufhören soll.
Was sollte im letzten Feld eines for-Loops stehen?
for(Start; Condition; Statement). Du hast im Statement eine reine Expression (keine Veränderung des Zustands).


Vielleicht kann mir jemand dabei helfen auch die Ausgabe als Bruch vorerst darzustellen, ohne die Sortierung.
Ehrlich gesagt kann ich mir darunter nichts vorstellen.
Meinst du
Code:
Zahl1 / Zahl2

oder

Zahl1 | Zahl2

oder

Zahl1
---------
Zahl2
cwriter
 
#3
Was sollte im letzten Feld eines for-Loops stehen?
for(Start; Condition; Statement). Du hast im Statement eine reine Expression (keine Veränderung des Zustands).



Ehrlich gesagt kann ich mir darunter nichts vorstellen.
Meinst du
Code:
Zahl1 / Zahl2

oder

Zahl1 | Zahl2

oder

Zahl1
---------
Zahl2
cwriter
Genau Zahl1 / Zahl2 soll ausgegeben werden.
Nur wie mache ich das so, dass es mit einem zweidimensionalen Array funktioniert.
Zuerst natürlich, sollte die Eingabe erfolgen.
:)
 

Technipion

Erfahrenes Mitglied
#4
Ehrlichgesagt sehe ich noch einige andere Problemchen im Code.
Deine main() und die Funktion einlesen() scheinen keinen Typ zu haben?

Außerdem ein kleiner Tipp direkt am Anfang: Die Variablen Steine[][] und i_zeile, i_spalte und k sind sogenannte globale Variablen, weil sie von überall (in deiner Quellcode-Datei) sichtbar sind. Eigentlich versucht man immer so gut es geht globale Variablen zu vermeiden, in seltenen Fällen (oder als Anfänger) kann man sie jedoch benutzen. Allerdings ist es dann immer schön sie als global zu kennzeichnen. Ich z.B. beginne ihre Namen dann immer mit "g_". Also aus int Steine[7][2]; würde dann int g_Steine[7][2];. Nur ein kleiner Tipp, damit erinnert man sich immer daran, dass diese Variablen global sind.

Zur for-Schleife: Hast du verstanden was cwriter gemeint hat? Falls ja poste mal deinen aktualisierten Code. Falls nein: Wo genau liegt das Problem?

Gruß Technipion
 

cwriter

Erfahrenes Mitglied
#5
Zuerst natürlich, sollte die Eingabe erfolgen.
Du inkrementierst die for-loop-Iterationsvariable nicht.
Nur wie mache ich das so, dass es mit einem zweidimensionalen Array funktioniert.
?
C:
printf("%d / %d", Steine[i][0], Steine[i][1]);
Es fällt mir ein bisschen schwer, deinen Kenntnisstand zu lesen. Die logische Herangehensweise bei diesen Dingen geht über die Typen.

Du hast einen Array von einem Array von ints namens Steine. Wir schreiben den Typ mal als [[int]]. Wenn du einmal dereferenzierst, bekommst du den Typ [int]. Das passt aber noch nicht für printf. Also musst du nochmals dereferenzieren. Das tatest du ja schon
Nun ist der 1x dereferenzierte Typ aber int[2]. D.h. du kannst auf 0 und 1 als Index zugreifen.
Vielleicht erklärt das die Herangehensweise ja etwas.

Deine main() und die Funktion einlesen() scheinen keinen Typ zu haben?
Sekiro nutzt C89, wo alles implizit int ist. Nicht mein Stil, aber naja...
Übrigens ist selbst in C11 noch implizit int - da aber mit einer Warnung. Aber anständige Menschen tun das nicht, da hast du schon recht ;)

Eigentlich versucht man immer so gut es geht globale Variablen zu vermeiden, in seltenen Fällen (oder als Anfänger) kann man sie jedoch benutzen. Allerdings ist es dann immer schön sie als global zu kennzeichnen. Ich z.B. beginne ihre Namen dann immer mit "g_". Also aus int Steine[7][2]; würde dann int g_Steine[7][2];. Nur ein kleiner Tipp, damit erinnert man sich immer daran, dass diese Variablen global sind.
Alles völlig richtig, aber für diese Aufgabenprogramme sollte das schon reichen - korrekterweise müsste man es lokal halten und per Pointer übergeben, aber es ist sowieso C89 - und damit ist die Chance, dass dieser Code irgendwo produktiv eingesetzt wird, nahezu 0 ;)

Gruss
cwriter
 
Zuletzt bearbeitet:
#6
Du inkrementierst die for-loop-Iterationsvariable nicht.
?
Jo total übersehen. Vielen Dank.

C:
printf("%d / %d", Steine[i][0], Steine[i][1]);
Es fällt mir ein bisschen schwer, deinen Kenntnisstand zu lesen. Die logische Herangehensweise bei diesen Dingen geht über die Typen.

Du hast einen Array von einem Array von ints namens Steine. Wir schreiben den Typ mal als [[int]]. Wenn du einmal dereferenzierst, bekommst du den Typ [int]. Das passt aber noch nicht für printf. Also musst du nochmals dereferenzieren. Das tatest du ja schon
Nun ist der 1x dereferenzierte Typ aber int[2]. D.h. du kannst auf 0 und 1 als Index zugreifen.
Vielleicht erklärt das die Herangehensweise ja etwas.


Sekiro nutzt C89, wo alles implizit int ist. Nicht mein Stil, aber naja...
Übrigens ist selbst in C11 noch implizit int - da aber mit einer Warnung. Aber anständige Menschen tun das nicht, da hast du schon recht ;)


Alles völlig richtig, aber für diese Aufgabenprogramme sollte das schon reichen - korrekterweise müsste man es lokal halten und per Pointer übergeben, aber es ist sowieso C89 - und damit ist die Chance, dass dieser Code irgendwo produktiv eingesetzt wird, nahezu 0 ;)

Gruss
cwriter[/QUOTE]
Mir ist schon bewusst das man eher zu lokalen Variablen neigt als zu globalen und diese dann an die jeweiligen Funktionen, die man verwenden möchte weitergibt. Die Aufgabe ist es vom Dozenten das Verständnis hinter globalen und lokalen Variablen klar zu machen. Nachher kommt noch eine weitere Funktion, der man dann Laufvariablen i und j übergeben soll. Diese Funktion soll berechnen heißen und die Zahlen der Dominosteine die gleich sind aneinander legen/sortieren.
Beispielsweise:
1. 5/2
2. 6/3
3. 1/4
4. 6/2
unsortiert

1. 5/2
2. 2/6
3. 6/3
4. 1/4
sortiert

Also 2 an 2 und 6 an 6
Dabei kann der Stein auch gedreht werden.
 
Zuletzt bearbeitet:
#7
?
Jo total übersehen. Vielen Dank.

C:
printf("%d / %d", Steine[i][0], Steine[i][1]);
Es fällt mir ein bisschen schwer, deinen Kenntnisstand zu lesen. Die logische Herangehensweise bei diesen Dingen geht über die Typen.

Du hast einen Array von einem Array von ints namens Steine. Wir schreiben den Typ mal als [[int]]. Wenn du einmal dereferenzierst, bekommst du den Typ [int]. Das passt aber noch nicht für printf. Also musst du nochmals dereferenzieren. Das tatest du ja schon
Nun ist der 1x dereferenzierte Typ aber int[2]. D.h. du kannst auf 0 und 1 als Index zugreifen.
Vielleicht erklärt das die Herangehensweise ja etwas.


Sekiro nutzt C89, wo alles implizit int ist. Nicht mein Stil, aber naja...
Übrigens ist selbst in C11 noch implizit int - da aber mit einer Warnung. Aber anständige Menschen tun das nicht, da hast du schon recht ;)


Alles völlig richtig, aber für diese Aufgabenprogramme sollte das schon reichen - korrekterweise müsste man es lokal halten und per Pointer übergeben, aber es ist sowieso C89 - und damit ist die Chance, dass dieser Code irgendwo produktiv eingesetzt wird, nahezu 0 ;)

Gruss
cwriter
Mir ist schon bewusst das man eher zu lokalen Variablen neigt als zu globalen und diese dann an die jeweiligen Funktionen, die man verwenden möchte weitergibt. Die Aufgabe ist es vom Dozenten das Verständnis hinter globalen und lokalen Variablen klar zu machen. Nachher kommt noch eine weitere Funktion, der man dann Laufvariablen i und j übergeben soll. Diese Funktion soll berechnen heißen und die Zahlen der Dominosteine die gleich sind aneinander legen/sortieren.
Beispielsweise:
1. 5/2
2. 6/3
3. 1/4
4. 6/2
unsortiert

1. 5/2
2. 2/6
3. 6/3
4. 1/4
sortiert

Also 2 an 2 und 6 an 6
Dabei kann der Stein auch gedreht werden.[/QUOTE]

Ich benutze momentan den Code Blocks Editor. Wenn ich den Code compilieren möchte, [\QUOTE]
Kann ich keine zweite Eingabe machen. Wieso ? mit Cygwin hatte es irgendwie geklappt.
Der Code sieht bis hierhin wie folgt aus:
C:
#include <stdio.h>
#include <math.h>
#include <stdlib.h>

int Steine[7][2];
int i_zeile, i_spalte, j, k;

main(){
    printf("Bitte geben Sie nun 7 Dominosteine ein\n");
    einlesen();
    for(k = 0; k < 7; k++)printf("%d. %d/%d\n", (k+1) ,Steine[k][0], Steine[k][1]);
}

einlesen(){
    for(i_zeile = 0; i_zeile < 7; i_zeile++){
        for(i_spalte = 0; i_spalte < 2; i_spalte++){
            scanf("%d. %d", i_zeile, &Steine[i_zeile][i_spalte]);
        }
    }
}
[\CODE]
 
Zuletzt bearbeitet:

cwriter

Erfahrenes Mitglied
#8
Ich benutze momentan den Code Blocks Editor. Wenn ich den Code compilieren möchte,
Kann ich keine zweite Eingabe machen. Wieso ? mit Cygwin hatte es irgendwie geklappt.
Der Code sieht bis hierhin wie folgt aus:
Naja, was macht denn scanf?
Wenn du "%d. %d" als scanf format string hast, dann wird nach i_zeile gelesen - bzw. auch nicht, das Programm sollte abstürzen.
Nimm das "%d." und die 'i_zeile' auis dem Scanf raus, dann solltest du alle Zahlen eingeben können.

Gruss
cwriter