C++ Einsteiger: Funktion wird ignoriert

obilaner

Lt. Junior Grade
Registriert
Apr. 2011
Beiträge
389
Hallo!

Ich übe grade Funktionen zu benutzen und ich habe versucht in einer Menuefunktion ( Menue ) eine Spielfunktion ( Zahlenraten ) zu laden mit einer einfachen IF Auswahl. Leider springt das Programm aus der Menuefunktion, statt etwas nach der IF Abfrage darin anzuzeigen.

Habe auch versucht einen Zufallswert an Menü weiterzugeben um diesen Wert von Menü an Zahlenraten weiterzugeben..

Hier der Code:


Code:
#include "includes.h"

using namespace std;

void Menue(int);                           // Menue Deklarieren
void zahlenraten(int);                  // Zahlenraten deklarieren





int main()                              // Hauptfunktion
{
        //int Versuche;

    int Zufall;
    srand(NULL);            // Random Seed Generieren
    Zufall=rand();  // Random Zahl verwenden
    Menue(Zufall);            // Menue öffnen

    return 0;          // Programm Ende
};




void Menue(int zufall)
{
    int temp;
    temp=zufall;          // Zufall Deklarieren
    system("cls");
    int eingabemenue;
    cout<<"Hauptmenue\n";
    cout<<"--------------------------\n";
    cout<<"1. Zahlenraten\n";
    cout<<"\n";
    cout<<"--------------------------\n";
    cin>>eingabemenue;
    if(eingabemenue=1)
    {
        cin.get();
        zahlenraten(temp);
    }

    else
    {
        cout<<"Error";
        cin.get();
    };
};






void zahlenraten(int derzahl)                               // Zahlenraten Funktion
{
    int Versuche;
    for(Versuche=0; Versuche==10; Versuche++)
    {


        system("cls");
        cout<<"Zahlenraten!\n";
        cout<<"----------------------\n";
        cout<<"\n";
        cout<<"Raten sie die Zahl, zwischen 1 un 100! Sie haben dafür maximal\n";
        cout<<"10 Versuche\n";
        cout<<"\n";
        cout<<"Bisherige Versuche: \n";
        cout<<Versuche;
        cout<<"Eingabe: ";
        cout<<derzahl;
        cin.get();


    }
};

In Includes. h ist folgendes:

Code:
#include <iostream>
#include <stdlib.h>
#include <string>
#include <cctype>
#include <ctype.h>
#include <stdio.h>
#include <chrono>
#include <unistd.h>
#include "windows.h"
#include "time.h"
#include <fstream>
 
Die Taste "1" auf deiner Tastatur gibt bei der Abfrage mit cin im besten Falle den ASCII Wert 49 bzw 31h zurück (Genauso wie z.B. das große A den Wert 65 aka 41h hat). Deine if Bedingung fragt aber nach der Zahl 1. 1 ist nicht gleich 49

Das ist eine Zuweisung, == ist der Vergleich.
Bei "if (x=1)" ist die if Bedingung aber true und muss dann auch ausgeführt werden.
 
Vergleichsoperator mit Zuweisungsoperator verwechselt. Typischer Anfängerfehler ;)

Stimmt, das mit dem ACSII stimmt auch nicht. Das wäre der nächste Fehler. Guck dir einfach mal eine Tabelle an.
 
Zuletzt bearbeitet:
Stimmt, das mit dem ACSII stimmt auch nicht
cin >> schreibt aber keine ASCII-Werte, sondern wertet den eingegebenen String unter dem Zieltypen aus. Insofern ist die Stelle bei ihm kein Fehler.

Dafür ist hier ein Fehler:
Code:
    for(Versuche=0; Versuche==10; Versuche++)
Zur Erinnerung: Der zweite Teil des for-Headers ist die Bedingung, bei der die Schleife weiterhin ausgeführt wird, nicht wann sie abgebrochen wird.

Du initialisierst also Versuche gerade mit dem Wert 0, führst die Schleife aber nur aus, wenn die Variable den Wert 10 hat. 0 ist aber nicht 10, also wird sie auch nie ausgeführt.
Korrekt wäre es so:
Code:
    for (int Versuche = 0; Versuche < 10; Versuche++)

Nebenbei kann (und sollte) man Zählervariablen in C++ auch immer im for-Header selbst deklarieren. Wir sind schließlich nicht bei C89 ;)
 
Zuletzt bearbeitet:
Nebenbei kann (und sollte) man Zählervariablen in C++ auch immer im for-Header selbst deklarieren. Wir sind schließlich nicht bei C89
Außer man braucht hinterher den Wert, bei welcher Iteration abgebrochen wurde und möchte nicht 2 Variablen nutzen X) Findet sich für alles ein brauchbares Szenario ;) Aber ja, wenn es nur für die Iteration selbst benötigt wird, sollte die Variable auch dort deklariert werden.
 
Gehört es überdies nicht zum guten Stil, Funktions- und Variablennamen mit einem kleinen Buchstaben anfangen zu lassen? Nur Klassennamen sollten mit einem Großbuchstaben anfangen:

Code:
void menue(int);
...
int zufall;
zufall=rand();
menue(zufall); 
...
void menue(int zufall) {...}
...
for(int versuche; versuche<10; versuche++) {...}

usw., man kann dann immer noch Konstrukte wie z.B. "int zufallZahl" (sog. Camel-Case) schaffen.

Und wenn man zu Beginn schon ganz streng ist, dann sollte man zu Beginn des Variablennamens auch auf irgendeine Weise den Typ der Variable vermerken: "int iZufallZahl", "int iVersuche". Siehe als Referenz dazu Ungarische Notation
 
Zuletzt bearbeitet:
Ungarische Notation zählt heute eigentlich nur noch als ein Relikt der '90er ('80er?). Bei ausreichend sprechenden Variablennamen kann ich persönlich keine Vorteile an ungarischer Notation entdecken.
Ergänzung ()

obilaner schrieb:
In Includes. h ist folgendes:

Code:
#include <iostream>
#include <stdlib.h> // besser -> #include <cstdlib>
#include <string>
#include <cctype> 
#include <ctype.h> // löschen ... du hast schon <cctype> inkludiert
#include <stdio.h> // besser -> <cstdio>
#include <chrono>
#include <unistd.h>
#include "windows.h"
#include "time.h"
#include <fstream>

In C++ gibt es für die alten C-Header Pendants, deren Namen sich bilden, indem man von dem alten C-Header-Namen das .h fallen läßt und vorne noch den Präfix c anfügt.
 
VikingGe schrieb:
cin >> schreibt aber keine ASCII-Werte, sondern wertet den eingegebenen String unter dem Zieltypen aus. Insofern ist die Stelle bei ihm kein Fehler.

Dafür ist hier ein Fehler:
Code:
    for(Versuche=0; Versuche==10; Versuche++)
Zur Erinnerung: Der zweite Teil des for-Headers ist die Bedingung, bei der die Schleife weiterhin ausgeführt wird, nicht wann sie abgebrochen wird.

Du initialisierst also Versuche gerade mit dem Wert 0, führst die Schleife aber nur aus, wenn die Variable den Wert 10 hat. 0 ist aber nicht 10, also wird sie auch nie ausgeführt.
Korrekt wäre es so:
Code:
    for (int Versuche = 0; Versuche < 10; Versuche++)

Nebenbei kann (und sollte) man Zählervariablen in C++ auch immer im for-Header selbst deklarieren. Wir sind schließlich nicht bei C89 ;)

Ja stimmt, super!!! Jetzt gehts weiter, Initialwert 1 und < statt == hat geholfen, vielen dank!
 
obilaner schrieb:
Ja stimmt, super!!! Jetzt gehts weiter, Initialwert 1 und < statt == hat geholfen, vielen dank!

Wieso Initialwert 1? Wenn du 10 Versuche haben möchtest, muß der Initialwert 0 sein, wenn deine Fortführungsbedingung "Versuche < 10" lautet.
 
Verwechslungen zwischen Zuweisung und Gleichheitsprüfung kannst du vermeiden, indem du das Literal bei einer Gleichheitsprüfung auf die linke Seite schreibst, denn ein "1=eingabemenue" haut dir der Compiler um die Ohren. Aber sieht dann vielleicht nicht mehr ganz so schön aus.
 
Guck dir auch nochmal Beispielcode für srand() an, dein aktueller Code wird immer die gleiche Zufallszahl erzeugen. Zwischen 1 und 100 liegt sie auch nicht.
 
Zuletzt bearbeitet:
mental.dIseASe schrieb:
Verwechslungen zwischen Zuweisung und Gleichheitsprüfung kannst du vermeiden, indem du das Literal bei einer Gleichheitsprüfung auf die linke Seite schreibst, denn ein "1=eingabemenue" haut dir der Compiler um die Ohren.
Jo. Vielleicht ist es besser, wenn man beim Compiler auch die Warnungen anschaltet. Dann weist der Compiler zumindest darauf hin, dass hier evtl. versehentlich eine Zuweisung vorgenommen wurde.

Und da Warnungen diese und ähnliche Dinge "abfangen" ist es vielleicht generell ein guter Tipp an Anfänger, Warnungen immer einzuschalten und wenn eine auftaucht, die dann auch nicht zu ignorieren.

Gruß
Andy
 
Zuletzt bearbeitet: (Rechtschreibung)
Guck dir auch nochmal Beispielcode für srand() an,
Noch besser: Gar nicht rand()/srand() verwenden, sondern die C++-Standardbibliothek nutzen:

Code:
#include <random>
...
std::random_device generator;
unsigned int randomNumber = generator(); // Noch nicht zwischen 1 und 100

Wenn man viele Zahlen braucht, bietet sich natürlich ein Mersenne-Twister an, aber für den Zweck hier reicht das random_device aus.
 
Zuletzt bearbeitet:
Zurück
Oben