Während Textdatei-Auslese Zahlen zählen

Lesterdor

Erfahrenes Mitglied
Guten Tag liebe Community,

ich habe einmal wieder ein Problem, was ich ohne Hilfe wohl nicht beseitigt bekomme. Dieses Mal habe ich einen kleinen Würfelgenerator geschrieben. Er funktioniert auch weitesgehend, aber ein ein Feature, was ich mir vorstelle, bekomme ich nicht umgesetzt.

Hier mein Code:
C:
//Includes für den Präprozessor einlesen:
#include <iostream>
#include <time.h> 
#include <fstream>
#include <string>

//Ersparung von std:: vor cout und cin:
using namespace std;

//Würfel-Simulations-Programm:
int main()
{
//Titel der Titelleiste ändern:    
system("title Würfel-Simulation by Dave"); 
//Consolenfarbe ändern: Hintergrund schwarz, Schriftfarbe grün:
system("color 02");
// Integer Variable für Würfelanzahl:
int Wurfe=0;   
cout<<"Anzahl der W\x81rfe:";
//Benutzer bestimmt nun die Anzahl:
cin>>Wurfe;
//"Zufallsgenerator" wird aktiviert:
srand(time(NULL));


//Textdatei "Würfel.ini" wird im Programmverzeichnis erstellt:
ofstream fout("Würfel.ini");
//Kleines Header für die "Würfel.ini" erzeugen:
fout<<"#############################################\n"<<Wurfe<<" mal wurde gewürfelt die Ergebnisse sind:\n#############################################\n"<<endl;
//Schleife gibt so lange eine Zahl zwischen 1 bis 7 aus, wie vorher angegeben. Dabei steht Zahl unter Zahl bis 1.000.000:
for (int i=1;i<=Wurfe;i++)
{
         if (i<10)
         {
         fout<<"      "<<i<<". Wurf: "<<rand()%6+1<<"\n";
         }
         else if(i>=10 && i<100)
         {
         fout<<"     "<<i<<". Wurf: "<<rand()%6+1<<"\n";
         }
          else if(i>=100 && i<1000)
         {
         fout<<"    "<<i<<". Wurf: "<<rand()%6+1<<"\n";
         }
          else if(i>=1000 && i<10000)
         {
         fout<<"   "<<i<<". Wurf: "<<rand()%6+1<<"\n";
         }
          else if(i>=10000 && i<100000)
         {
         fout<<"  "<<i<<". Wurf: "<<rand()%6+1<<"\n";
         }
           else if(i>=100000 && i<1000000)
         {
         fout<<i<<". Wurf: "<<rand()%6+1<<"\n";
         }
}
// Schließt "Würfel.ini":
fout.close();


cout<<"\n\n\t\t\t\t°...Fertig!...°\n\n";
cout<<"\x99 \bffnen Sie bitte die Datei \"W\x81rfel.ini\", um die gew\x81rfelten Zahlen anzusehen.\nDie Datei befindet sich im selben Verzeichnis, wo sich auch die \"W\x81rfel.exe\"\nbefindet.\n\n\t"<<endl;
cout<<"M\x94 \bchten Sie die Daten in der Console angezeigt haben: "<<endl;
cout<<"\t\t\t[Ja] oder [Nein]: ";
// Eingabe für Textausgabe in der Console:
string Eingabe;
Eingabe.clear();
cin>>Eingabe;
//Bei Nein:
  if (Eingabe=="Nein"||Eingabe=="nein")
{
system("CLS");
cout<<"\n\x99 \bffnen Sie bitte die Datei \"W\x81rfel.ini\", um die gew\x81rfelten Zahlen anzusehen.\nDie Datei befindet sich im selben Verzeichnis, wo sich auch die \"W\x81rfel.exe\"\nbefindet.\n\n\t\n\n"<<endl;                          
}
//Bei Ja wird der ganze Text der "Würfel.ini" auf der Console ausgegeben:
 if (Eingabe=="Ja"||Eingabe=="JA"||Eingabe=="ja"||Eingabe=="jA")
{
    system("CLS");
    ifstream f;  // Datei-Handle
    string s;
    f.open("Würfel.ini", ios::in); // Öffne Datei aus Parameter
    while (!f.eof())          // Solange noch Daten vorliegen
    {
        getline(f, s);        // Lese eine Zeile
        cout<< s << endl;    // Zeige sie auf dem Bildschirm
    }
    f.close();   
    cout<<"\n\nSie k\x94nnen die Daten immer noch in der Textdatei \"W\x81rfel.ini\" ansehen und mit\nihnen arbeiten.\nDie Datei befindet sich im selben Verzeichnis, wo sich auch die \"W\x81rfel.exe\"\nbefindet.\n\n"<<endl;
}
//Bei Eingabe weder Nein noch Ja:
 if (Eingabe!="Nein"&&Eingabe!="nein"&&Eingabe!="Ja"&&Eingabe!="JA"&&Eingabe!="ja"&&Eingabe!="jA")
{
 system("CLS");
 cout<<"\nEntschuldigung, aber Sie haben eine falsche Eingabe get\x84tigt."<<endl;        
 cout<<"\x99 \bffnen Sie bitte die Datei \"W\x81rfel.ini\", um die gew\x81rfelten Zahlen anzusehen.\nDie Datei befindet sich im selben Verzeichnis, wo sich auch die \"W\x81rfel.exe\"\nbefindet.\n\n\t"<<endl;        
}
//Programmende:
system("PAUSE");
return 0;
}

Wie ihr dem Code entnehmen könnt, wird der Benutzer gefragt, wie oft gewürfelt werden soll. Das Programm gibt "zufällig" eine Zahl zwischen 1 und 6 (einschließlich 6) aus. Die Werte werden in einer Textdatei gespeichert, die ich zum Testen einfach Würfel.ini genannt habe. Ein kleines Beispiel, falls der Benutzer 6x Würfeln eintippt. Die Würfel.ini sieht dann so aus:

#############################################
6 mal wurde gewürfelt die Ergebnisse sind:
#############################################

1. Wurf: 5
2. Wurf: 4
3. Wurf: 3
4. Wurf: 1
5. Wurf: 2
6. Wurf: 2

Nach diesem Durchlauf, wird der Anwender noch einmal gefragt, ob er die Ergebnisse in der Console sehen möchte, oder einfach selbst die Datei Würfel.ini öffnen und somit Einsicht haben möchte.

Bis hier hin funktioniert alles wie geplant...

Am Ende möchte ich eine Zusammenfassung haben, sodass in der Textdatei folgendes geschrieben wird:
Zusammenfassung:

Die 1 wurde Xmal gewürfelt
Die 2 wurde Xmal gewürfelt
Die 3 wurde Xmal gewürfelt
Die 4 wurde Xmal gewürfelt
Die 5 wurde Xmal gewürfelt
Die 6 wurde Xmal gewürfelt

Also sollte das Programm am Ende jede Zeile auslesen und in einer Variable festhalten, wie oft die 1, 2 , 3, 4, 5, 6 gewürfelt wurde.
Achtung, einfach nur die Zahlen auslesen könnte Schwierigkeiten bereiten, denn falls der 1. Wurf : 1 ist, stehen in der ersten Zeile zwei Einsen, was beim Zählen ja falsch wäre, da sie bis zu der Zeile in Wirklichkeit nur einmal gewürfelt wurde.

Mein Problem ist generell, wie ich Zeilen auslese und auf deren Zeichen prüfe und sie ggf. in eine Variable speichere. Hinzu kommt das oben genannte Problem, dass nicht jeder Wert zur Zählung genommen werden darf, sofern die Ziffer nur den Wurf angibt.

Ich gebe zu, dass es etwas kompliziert ist, zumindest für mich, da ich noch Anfänger bin. Dennoch hoffe ich, dass mir jemand helfen kann und danke im Voraus recht herzlich und wünsche euch ein schönes Wochenende
 
Zuletzt bearbeitet:
Wie wäre es, wenn du nach jedem Wurf die Anzahl der Gewürfelten zahlen fest hältst?
Also bspw. ein Array aus ints und dann einfach wenn das was gewürfelt wurde Array[Würfelergebnis]++ oder sowas?
Das kannste dann am schluss auch in der Datei festhalten.
 
Hallo ihr Beiden,

danke für eure schnelle Hilfe. Eure Lösung, während des Würfelns zu zählen ist mir nach dem Post auch in den Sinn gekommen ;) .

Allerdings hänge ich etwas an der Umsetzung. Wie muss denn meine If-Bedingung lauten, ich habe:
Code:
for (int i=1;i<=Wurfe;i++)
{
        fout<<rand()%6+1<<"\n";
       if (rand()%6+1==1)
       {
       Counter[0]++;
       }
}
fout<<"Die 1 wurde "<<Counter[0]<<" gewürfelt\n";
Das ist aber falsch, da er mir immer 3 ausgibt, egal ob eine 1 oder keine dabei war.
 
Zuletzt bearbeitet:
Hallo ihr Beiden,

danke für eure schnelle Hilfe. Eure Lösung, während des Würfelns zu zählen ist mir nach dem Post auch in den Sinn gekommen ;) .

Allerdings hänge ich etwas an der Umsetzung. Wie muss denn meine If-Bedingung lauten, ich habe:
Code:
for (int i=1;i<=Wurfe;i++)
{
       fout<<rand()%6+1<<"\n";
       if (rand()==1)
       {
       Counter[0]++;
       }
}
fout<<"Die 1 wurde "<<Counter[0]<<" gewürfelt\n";
Die ist aber falsch, denn er gibt mir immer eine sehr lange Zahl aus.
Vermutlich hast du vergessen das Array auch ordentlich mit Nullen zu initialisieren.

Dann ist dein Fehler, das du eine ganz andere Zufallszahl ausgibst, und dann nochmal eine Zahl ziehst und diese dann mit 1 vergleichst.

Die Bedingung kannst du komplett weglassen:
C++:
int count[6] = { 0, 0, 0, 0, 0, 0 };

for (...) {
  int zufallszahl = ...;

  fout << zufallszahl;
  
  count[zufallszahl - 1]++;
}
Gruß
 
Zuletzt bearbeitet:
Hallo Deepthroat,

wie immer top Antwort, weiter so ;)

Ich taste mich Schritt für Schritt an deine Vorschläge, ich bin jetzt dabei einen anderen Zufallsgenerator zu implementieren:

Code:
/* get integer random number in range a <= x <= e */
int irand( int a, int e)
{
    double r = e - a + 1;
    return a + (int)(r * rand()/(RAND_MAX+1.0));
}

Mein Problem ist, ich weiß nicht wie ich ihn einstelle, dass er eine Zahl zwischen 1 und 6 (einschließlich 6) generiert. Ich habe e und a schon durch Zahlen ersetzt, aber der Compiler zeigte immer Fehler an.

Eine kleine Anmerkung:
Ich weiß, dass ich hier viel poste, was für ein Profi innerhalb von Minuten zu lösen geht, deshalb möchte ich hier nicht den Anschein erwecken, dass ich einfach Codes heraussuche und euch die Arbeit für mein Programm überlasse, dass ihr mir den Code anpasst. Im Gegenteil, ich probiere es immer selbst, nur wenn es nicht funktioniert, wende ich mich an das Forum, wofür es ja auch da ist ;)

Ich schreibe die Anmerkung nur, weil ich mir beim Durchlesen immer so vorkomme, als ob ich nichts könnte (Anfänger halt), möchte nur evtl. einer falschen Erscheinung vorbeugen :rolleyes:

Danke Deepthroat, aber der Compiler gibt mir folgende Meldung aus:
"a function-definition is not allowed here before '{' token"
und er zeigt auf die erste {-Klammer (fett markierte):
Code:
/* get integer random number in range a <= x <= e */
int irand( int a, int e)
{
    double r = e - a + 1;
    return a + (int)(r * rand()/(RAND_MAX+1.0));
}

In Ordnung, habe meinen Fehler selbst gefunden, habe im Eifer des Gefechts die Funktion in der int main() definiert, muss natürlich davor... läuft jetzt.

P.S: Sorry für PN @ Deepthroat
 
Zuletzt bearbeitet:
Hi.
Ich taste mich Schritt für Schritt an deine Vorschläge, ich bin jetzt dabei einen anderen Zufallsgenerator zu implementieren
Du kennst wohl noch keine selbstdefinierten Funktionen, oder?!

Den Quelltext der irand Funktion übernimmst du 1:1 so wie er dastand. Die Funktion kannst du dann innerhalb deiner Schleife so verwenden:
C++:
int zufallszahl = irand(1, 6); // Zufallszahl im Intervall [1, 6]
Gruß

PS: Es kam mir übrigens nicht so vor, dass du anderen nur die Arbeit überlassen willst und selbst nichts tust.
 
Zuletzt bearbeitet:
Danke Deepthroat, aber der Compiler gibt mir folgende Meldung aus:
"a function-definition is not allowed here before '{' token"
und er zeigt auf die erste {-Klammer (fett markierte):
Funktionen kann man nicht schachteln. Du darfst die Definition nicht in die main Funktion schreiben, sondern davor.

Gruß

\edit: Ach, hast du ja selbst schon gemerkt... :)
 
Zuletzt bearbeitet:
Nabend ;D

langsam kommt es mir hier fast wie ein Live-Chat vor ;)

Ich habe noch 2 Anliegen, bis ich alles erfüllt habe, was ich mir für das Programm vorgestellt habe. Es geht dieses Mal um Formatierung.

1. Ich möchte die Idee von Deepthroat implementieren, dass Zahl unter Zahl steht. Ich habe es mit vielen IF-Funktionen gelöst, aber nur bis 1 Mio. Dank Deepthroat kenne ich nun eine Methode, die das mit weniger Code hinbekommt. Leider weiß ich nicht, wie ich Zeile für Zeile auslesen soll, um die längste zu ermitteln.

2.
Code:
for (int i=1;i<=Wurfe;i++)
{
         int Random= irand(1, 6);

         fout<<i<<". Wurf: "<<Random<<"\n";
         Counter[Random-1]++;

}
fout<<"Die 1 wurde "<<Counter[0]<<" gewürfelt\n";
fout<<"Die 2 wurde "<<Counter[1]<<" gewürfelt\n";
fout<<"Die 3 wurde "<<Counter[2]<<" gewürfelt\n";
fout<<"Die 4 wurde "<<Counter[3]<<" gewürfelt\n";
fout<<"Die 5 wurde "<<Counter[4]<<" gewürfelt\n";
fout<<"Die 6 wurde "<<Counter[5]<<" gewürfelt\n";
// Schließt "Würfel.ini":
fout.close();
Hieraus lässt sich erkennen, dass er unter den gewürfelten Zahlen ausgibt, wie oft was gewürfelt wurde. Wie bekomme ich diese Ausgaben nach ganz oben:

#############################################
6 mal wurde gewürfelt die Ergebnisse sind:
#############################################
Die 1 wurde 1 gewürfelt
Die 2 wurde 1 gewürfelt
Die 3 wurde 1 gewürfelt
Die 4 wurde 2 gewürfelt
Die 5 wurde 1 gewürfelt
Die 6 wurde 0 gewürfelt

1. Wurf: 1
2. Wurf: 4
3. Wurf: 2
4. Wurf: 5
5. Wurf: 4
6. Wurf: 3

Die Würfe sollen schon angezeigt werden, zum einen als Beweis für die Richtigkeit der Anzahl, also dass der Anwender ggf. nachzählen kann und zum anderen für evtl. Untersuchungen z. B. welche Augen jeder 5te Wurf hat oder so ;) .

Ich poste die beiden "letzten" Hindernisse jetzt in einem Post, damit ich nicht ständig den Thread hier pushe, andere haben ja auch Probleme.

Wie immer danke im Voraus
 
Nabend ;D

langsam kommt es mir hier fast wie ein Live-Chat vor ;)
Nu war ich aber kurz weg... ;)
1. Ich möchte die Idee von Deepthroat implementieren, dass Zahl unter Zahl steht. Ich habe es mit vielen IF-Funktionen gelöst, aber nur bis 1 Mio. Dank Deepthroat kenne ich nun eine Methode, die das mit weniger Code hinbekommt. Leider weiß ich nicht, wie ich Zeile für Zeile auslesen soll, um die längste zu ermitteln.
Nun willst du schon wieder die Datei auslesen. Ist das ein Faible von dir? ;-]

Da du die max. Anzahl von Würfen kennst, ist es doch simpel vorher die benötigte Breite der Zahl festzustellen. Du müßtest nur feststellen wieviel Ziffern die Zahl hat - Tipp: Modulo-Operator und Dezimalsystem.
Hieraus lässt sich erkennen, dass er unter den gewürfelten Zahlen ausgibt, wie oft was gewürfelt wurde. Wie bekomme ich diese Ausgaben nach ganz oben
Ganz einfach: indem du es ganz zuerst reinschreibst. ;-)

Der Einfachheit halber könntest du erstmal alles nur in einen ostringstream ausgeben:
C++:
#include <sstream>

ostringstream out;
Die Variable out kannst du genau so verwenden wie einen Dateistream oder cout auch. Es wird nur alles im Speicher gehalten. Wenn das Würfeln fertig ist, dann schreibst du einfach die Zusammenfassung in die Datei und danach alles was in out gespeichert ist:
C++:
fout << out.str();
Gruß
 

Neue Beiträge

Zurück