Game Of Life - Einlesen / Ausgeben einer tabellarischen .txt

gutsch

Mitglied
Hey!

Wie der Titel sagt, soll es um das Game Of Life gehen. In einer, wie ich finde, einfachen Form. Das erstellen an sich mit Ausgabe über die Konsole dürfte kein großes Problem darstellen. Darum soll es letztlich also nicht gehen.
Mein Problem ist, dass ich noch nie Dateien eingelesen bzw. in Dateien ausgegeben habe. Mir liegt z.B. eine solche .txt vor:

Code:
#Life 1.06
1 3
0 1
1 0
1 2
2 0

Einfach durch Leerzeichen getrennt. Das sind quasi Koordinaten von lebendigen Zellen. Das soll eingelesen werden und anhand dessen das Programm mit i Iterationen laufen. Die Ausgabe der einzelnen Iterationen soll auf dem Bildschirm erfolgen. Zusätzlich soll die letzte Iteration in eine .txt geschrieben werden. In dem gleichen Format wie sie eingelesen wurde. Zeilen mit einem "#" am Anfang sind Kommentare und sollen überlesen werden.
Und da stehe ich schon vor den ersten Problemen:
Ich habe wie gesagt keine Ahnung vom einlesen und ausgeben von / in Dateien. Ich habe jetzt ein wenig rumprobiert, das stimmt mich aber noch nicht wirklich glücklich. Vor allem weiß ich nicht, wie ich die Zeilen mit einem "#" ignoriere, oder wie ich die einzelnen Koordinaten irgendwo übergebe, damit ich die verwenden kann.

Ausserdem soll noch folgendes gemacht werden (Leider auch noch nie mit gearbeitet):
Beim Programmaufruf sind 4 Parameter zu übergeben: die Dimensionen n (Zeilen) und m (Spalten) sowie der Name der Eingabedatei und die Anzahl der Iterationen i

Wäre super wenn mir jemand helfen könnte :]

edit:
Arbeite mit Visual Studio oder Dev-C++
Vorgabe ist, das ganze in C zu machen.

edit 2:
Ich habe es immerhin soweit, dass ich das, was in der einen Datei steht, in eine andere schreiben kann. Im Prinzip wollte ich das nur machen, um drauf zu kommen, wie es weiter geht. Wirklich geholfen hat es leider nicht :/

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

// Main
int main(int argv, char **argc) {
	
	const char LIFE[] = "life.txt";
	const char LIFEOUT[] = "lifeout.txt";
	FILE *ein = fopen (LIFE, "r");
	FILE *aus = fopen (LIFEOUT, "w");

	int i = 0, n = 1;
	char c;
	char buffer[100];

	if ( ( ein == NULL) || (aus == NULL ) ) {
		printf ("Fehler beim Oeffnen der Datei\n");
		EXIT_FAILURE;
	} else {
		while ( ( c = fgetc(ein) ) != EOF ) {
			fputc (c, aus);
			putc (c, stdout);
		}
	}	

	fclose(ein);
	fclose(aus);
	
	system("PAUSE");
	return 0;
}

Bestimmt nicht schön, aber es sind ja auch nur Anfänge :/
 
Zuletzt bearbeitet:
Du musst die Datei zeilenweise einlesen. Dazu prüfst du, ob das eingelesene Zeichen einem Umbruch (\n, oder \r\n (vorsicht, sind 2 zeichen)) entspricht. Wenn ja, bist du in einer neuen Zeile. Ist dann das erste Zeichen eine Raute, dann liest du solange weiter ein, bis das nächste Zeichen wieder ein Umbruch ist (oder Dateiende). Wenn keine Raute am Anfang steht, sind es deine Koordinaten.
 
Das Prinzip an sich ist klar. Erschließt sich ja aus der Aufgabe. Aber ich versuche immer noch das um zu setzen. Also das mit dem Auslesen und Ausgeben ohne #-Zeilen. Ich kriege es einfach nicht hin oO
Wenn ich das habe kann es weiter gehen. Denn da tun sich noch genug Fragen auf :/ Aber ich versuche fleißig weiter.
 
Hi.
Du musst die Datei zeilenweise einlesen. Dazu prüfst du, ob das eingelesene Zeichen einem Umbruch (\n, oder \r\n (vorsicht, sind 2 zeichen))
Das ist unnötig wenn man die Datei im Textmodus öffnet. Es ist immer nur \n.

Zeilenweise auslesen macht man mit fgets.

Danach mit sscanf weiterarbeiten.

\edit: @gutsch
C:
...
		EXIT_FAILURE;
Diese Anweisung hat keine Wirkung. Du meintest
C:
return EXIT_FAILURE;
Aber du solltest der Ordnung halber alle Dateien schließen falls eine nicht geöffnet werden konnte.

Und c sollte vom Typ int sein.
 
Zuletzt bearbeitet:
Ok will ich mal versuchen.
Habe mich gerade eben schon gefragt warum \n bzw \r\n
Wo wird das benötigt?

edit:

Oh gar nicht aufgefallen

C++:
if ((ein == NULL) || (aus == NULL)) {
		printf("Fehler beim Oeffnen der Datei\n");
		fclose(ein);
		fclose(aus);
		return EXIT_FAILURE;

das wäre dann das. Aber mit fgets komm ich nicht weiter.
Versuche gerade erstmal das gleich wie oben mit fgetc hin zu bekommen. Also auslesen und in andere Datei schreiben. Schritt für Schritt halt. Und zumindest das klappt schon mal ^^

C++:
[...]
else {
		while(fgets(name, MAX, ein)){
			fputs(name, stdout);
			fputs(name, aus);}



// edit:
Mir scheint, mir erschließt sich gerade der Sinn von sscanf ;)
 
Zuletzt bearbeitet:
C++:
	int i, j;
	char name[MAX];
	const char LIFE[] = "life.txt";
    const char LIFEOUT[] = "lifeout.txt";
    FILE *ein = fopen (LIFE, "r");
    FILE *aus = fopen (LIFEOUT, "w");

	if ((ein == NULL) || (aus == NULL)) {
		printf("Fehler beim Oeffnen der Datei\n");
		fclose(ein);
		fclose(aus);
		return EXIT_FAILURE;
	} else {
		while(fgets(name, MAX, ein)){
			sscanf(name,"%d %d",&i, &j);
			printf("%d %d\n", i, j);
			fprintf(aus, "%d %d\n", i, j);
		}
	}

Immerhin stimmt die Ausgabe ja schon mal irgendwie.

Steht sowohl in der Datei als auch in der Konsole. Erste Zeile ist halt ursprünglich eine Raute. Bin mir nicht sicher, wie ich die da nun heraus bekomme :/
C++:
-858993460 -858993460
1 3
0 1
0 2
1 6


Ok. Habe was:

C++:
while(fgets(name, MAX, ein)){
			sscanf(name,"%d %d",&i, &j);
			if(i >= 0 && i <= MAX) {
				printf("%d %d\n", i, j);
				fprintf(aus, "%d %d\n", i, j);
				b[n][m] = a[i][j];
				n++;
				m++;
			}
		}

Bestimmt nicht die schönste Lösung, aber so isses raus und ich hab die Koordinaten noch woanders liegen, um die weiter nutzen zu können. (#define MAX 20 nebenbei. Also sollte max n 20x20 Feld werden)
Oder liege ich da nun komplett falsch?
 
Zuletzt bearbeitet:
Du solltest prüfen ob die Eingabe bei sscanf überhaupt geklappt hat:
C:
if (sscanf(name, "%d %d", &i, &j) == 2) {
   ...
} else {
  // Fehler: konnte Zeile nicht lesen.
}

Und die Zeilen die mit einer Raute anfangen, kannst du so ignorieren:

C:
if (name[0] == '#') continue;
 
C++:
while(fgets(name, MAX, ein)){
			if (sscanf(name,"%d %d",&i, &j) == 2) {
				if (name[0] == '#') continue;
				else {
				printf("%d %d\n", i, j);
				fprintf(aus, "%d %d\n", i, j);
				b[n][m] = a[i][j];
				n++;
				m++;
				}
			} else;
		}

So? Ich mein: Es funktioniert.

Oder vielleicht so?

C++:
while(fgets(name, MAX, ein)){
			if (sscanf(name,"%d %d",&i, &j) == 2) {
				printf("%d %d\n", i, j);
				fprintf(aus, "%d %d\n", i, j);
				b[n][m] = a[i][j];
				n++;
				m++;
			} 
		}

Funktioniert auch ...
 

Neue Beiträge

Zurück