Anfängerfragen zu Dateioperationen und Arrays

Radmor

Grünschnabel
Hallo zusammen,

ich bin im Moment dabei das Spiel Hangman als Konsolenanwendung zu programmieren.
Dabei habe ich noch Zwei Probleme.

In dem Spiel werden die Wörter aus einer Textdatei eingelesen.

Als erstes wird ein Schwierigkeitsgrad eingegeben:
Code:
  int Versuche;
  char Datei[20]="";
  switch (schwierigkeitsgrad())
  {
    case 'e':
    strncpy (Datei, "einfach.txt", 12);
	Versuche = 8;
    break;

	case 'n':
    strncpy (Datei, "normal.txt", 11);
	Versuche = 12;
    break;

	case 's':
    strncpy (Datei, "schwer.txt", 11);
	Versuche = 16;
    break;
  }

Die Funktion schwierigkeitsgrad() fragt den User nach einem Schwierigkeitsgrad.


Als nächstes wird dann die Anzahl der Zeilen in der Datei gezählt:
Code:
  ifstream in ( Datei );

  int zeilenanzahl = 0;
  string line;
  while (getline (in, line))
  {
    zeilenanzahl = zeilenanzahl + 1;
  }

Jetzt ist ja die Anwendung am Ende der Textdatei angekommen. (oder liege ich da falsch ?)

Nun muss ich ja der Anwendung mitteilen, dass sie wieder von oben mit dem einlesen anfangen soll, damit der Zufallsgenerator ein Wort auswählt.

Das neuladen der Datei habe ich so realisiert:
Code:
  in.close();
  in.open ( Datei );

Der Zufallsgenerator sieht so aus:
Code:
  char Ergebnis[50]="";
  srand (time (NULL));
  for (int i = 0; i <= (rand() % zeilenanzahl); i = i + 1)
  {
    in >> Ergebnis;
  }

Wenn ich das jetzt in der Schule erstelle (Borland C++ Builder 5) funktioniert es einwandfrei.
Zuhause arbeite ich aber mit Visual C++ Express 2005.
Dort kann ich die .exe zwar erstellen. Allerdings scheint es dann nicht zu funktionieren, da dann das Wort was er aus der Datei laden möchte nicht existiert.
Das Char-Array Ergebnis ist dann nämlich leer.

Problem1: Was mache ich da falsch ?

In der Schule hab ich dann noch eine Abfrage am Ende des Spiels eingebaut, welche den User fragt ob er nochmal spielen möchte. Wenn er mit ja antwortet, springt die Anwendung direkt zur Ersten Codezeile im Programm.
Manchmal kommt es dann im Programm vor, dass aufeinmal bei einem Wort schon ein paar Buchstaben gegeben sind.

Problem2: Wie kann ich diese Char Arrays komplett resetten ?

Gruß
Radmor
 
Zuletzt bearbeitet:
Hi.
Als nächstes wird dann die Anzahl der Zeilen in der Datei gezählt:
Code:
  ifstream in ( Datei );

  int zeilenanzahl = 0;
  string line;
  while (getline (in, line))
  {
    zeilenanzahl = zeilenanzahl + 1;
  }

Jetzt ist ja die Anwendung am Ende der Textdatei angekommen. (oder liege ich da falsch ?)

Nun muss ich ja der Anwendung mitteilen, dass sie wieder von oben mit dem einlesen anfangen soll, damit der Zufallsgenerator ein Wort auswählt.

Das neuladen der Datei habe ich so realisiert:
Code:
  in.close();
  in.open ( Datei );
Das Problem ist, das der Stream in einem Fehlerzustand ist (fail und eof) und deshalb auf dem Stream keine Eingabeoperationen mehr gemacht werden können.
Probier's mal so:
C++:
in.seekg(0);

Oder mit deiner Methode:
C++:
in.close();
in.clear();
in.open( Datei );
Der Zufallsgenerator sieht so aus:
Code:
  char Ergebnis[50]="";
  srand (time (NULL));
  for (int i = 0; i <= (rand() % zeilenanzahl); i = i + 1)
  {
    in >> Ergebnis;
  }
Hm. Also, erstmal erreicht man durch die Modulo-Opertion keine guten Zufallszahlen, aber das dürfte dir am Anfang ziemlich egal sein.

Dann willst du mit der Schleife vermutlich eine zufällige Zeile lesen. Der Zufall dürfte aber recht schnell zuschlagen, denn du generierst ja bei jedem Schleifendurchlauf eine neue Zufallszahl.

Außerdem hast du vorher doch bereits die Zeilen schön mit getline in einen std::string gelesen - jetzt machst du es plötzlich wortweise mit einem C String?!

Desweiteren wäre es vermutlich sinnvoller die Datei einmal zulesen und die Zeilen in einen Container zu speichern wo du einfach indiziert drauf zugreifen kannst.

In der Schule hab ich dann noch eine Abfrage am Ende des Spiels eingebaut, welche den User fragt ob er nochmal spielen möchte. Wenn er mit ja antwortet, springt die Anwendung direkt zur Ersten Codezeile im Programm.
Manchmal kommt es dann im Programm vor, dass aufeinmal bei einem Wort schon ein paar Buchstaben gegeben sind.

Problem2: Wie kann ich diese Char Arrays komplett resetten ?
"Komplett resetten"? Also da weiß ich nicht genau was du damit meinst. Evtl. das:
C++:
cin.ignore(1000, '\n');
Gruß
 
Hallo,

danke für deinen Beitrag.

Mein erstes Problem ist nun gelöst.
Mit Containern kenne ich mich leider noch nicht aus.

Das mit dem Zufallsgenerator hab ich jetzt so gelöst:
Code:
  srand (time (NULL));

  int zufallszahl = rand() % zeilenanzahl;

  for (int i = 0; i <= zufallszahl; i = i + 1)
  {
    in >> Ergebnis;
  }

Zu Problem 2:

Ich möchte, dass die "benutzen" Arrays für das Wort und die Striche komplett geleert werden, damit sie wieder im selben Zustand wie beim Programmstart sind.

Sonst passiert es manchmal, dass wenn man nochmal spielen möchte schon manche Buchstaben in dem neuen Wort gegeben sind.

Gruß
Radmor
 
Zu Problem 2:

Ich möchte, dass die "benutzen" Arrays für das Wort und die Striche komplett geleert werden, damit sie wieder im selben Zustand wie beim Programmstart sind.

Sonst passiert es manchmal, dass wenn man nochmal spielen möchte schon manche Buchstaben in dem neuen Wort gegeben sind.
Also, ich rate mal weiter da ich nicht weiß wie du mit den Arrays umgehst.
C++:
#include <cstring>

char w[20];

memset(w, 20, '\0');
Gruß
 
Das mit dem memset funktioniert leider nicht.

Mit den Arrays geschieht folgendes:

Zuerst werden die Arrays deklariert:
Code:
  char Ergebnis[50]="";
  char Wort[50]="";

Danach wird aus der Datei je nach Zufallszahl ein Wort in das Array geladen:
Code:
  srand (time (NULL));

  int zufallszahl = rand() % zeilenanzahl;

  for (int i = 0; i <= zufallszahl; i = i + 1)
  {
    in >> Ergebnis;
  }

Danach werden in das Wort-Array Striche geschrieben.
Und zwar so viele, wie das zu erratene Wort lang ist:
Code:
  for (int i = 0; Ergebnis[i] != '\0'; i = i + 1)
  {
    Wort[i] = '-';
  }

Wenn der Spieler dann später ein Wort richtig erraten hat, wird es mit:
Code:
  for (int i = 0; i != laenge + 1; i = i + 1) 
  {
    if (Buchstabe == Ergebnis[i])
	{
	  Wort[i] = Buchstabe;
	}
  }
in das Array geschrieben.
 
Zurück