"cin" wird während Schleife übergangen



  • Hi, ich erarbeite mir mit dem Buch "C++ für Spieleprogrammierer" ein paar Grundlagen.

    Ich schreibe derzeit ein Programm, welches einfach ein Menü enthält. Je nach Eingabe wird dann ein Menüpunkt angewählt.
    Solange ich die Eingabe "1" mache, funktioniert das Programm, wie gewollt.
    Das heißt, es wird quasi ein Array von Punkten ausgegeben und danach wird das Menü wieder aufgerufen.

    Fehlerbeschreibung: Wenn ich nun "2" als Eingabe eingebe, werden zunächst wie in der Funktion "feld_besetzen" beschrieben, die x- Koordinate, y- Koordinate und der Name abgefragt. Nach der Eingabe des Namens startet eine Endlosschleife:

    Auswahl: Land, Wasser, Luft, Lava
    x - Position (1-10): 2
    y - Position (1-10): 2
    Name: Luft
    // ab hier beginnt die Endlosschleife
    1 - Spielfeld anzeigen
    2 - Feld besetzen
    3 - Felddaten anzeigen
    4 - Spielfeld loeschen
    5 - Programm beenden
    Auswahl: Land, Wasser, Luft, Lava
    x - Position (1-10): y - Position (1-10): Name: 1 - Spielfeld anzeigen
    2 - Feld besetzen
    3 - Felddaten anzeigen
    4 - Spielfeld loeschen
    5 - Programm beenden
    Auswahl: Land, Wasser, Luft, Lava
    x - Position (1-10): y - Position (1-10): Name: 1 - Spielfeld anzeigen
    2 - Feld besetzen
    3 - Felddaten anzeigen
    4 - Spielfeld loeschen
    5 - Programm beenden

    Meiner Meinung nach müsste das Programm, nachdem die Funktion "feld_besetzen" abgearbeitet wurde, zum "break;" in case 2 springen, danach aus der switch - Anweisung heraus und wieder in der ersten Zeile der do - while - Anweisung anfangen.

    //main Datei
    
    #include <iostream>
    #include "Funktionen_Deklaration.h"
    using namespace std;
    int menue_eingabe;
    
    int main ()
    {
    	//Array definieren
    	for (int i = 0; i < 10; i++) {
    		for (int k = 0; k < 10; k++) {
    			spielfeld[i][k] = 0;
    		}
    	}
    	//Array definieren Ende
    
    	do
    	{
    		cout << "1 - Spielfeld anzeigen\n";
    		cout << "2 - Feld besetzen\n";
    		cout << "3 - Felddaten anzeigen\n";
    		cout << "4 - Spielfeld loeschen\n";
    		cout << "5 - Programm beenden\n";
    
    		cin >> menue_eingabe;
    
    		switch (menue_eingabe)
    		{
    			case 1:
    				spielfeld_anzeigen();
    				break;
    			case 2:
    				feld_besetzen();
    				break;
    			case 3:
    				//felddaten;
    				break;
    			case 4:
    				//spielfeld_loeschen;
    				break;
    			case 5:
    				break;
    			default:
    				cout << "Falsche Eingabe. Programm wird beendet";
    		}
    
    	} while (menue_eingabe < 5);
    
    	return 0;
    }
    

    Jetzt noch die cpp Datei, die die Funktionen enthält:

    // Definition der Funktionen
    #include "Funktionen_Deklaration.h"
    #include <iostream>
    using namespace std;
    
    /*int menue(void) {
    	int menue_eingabe;
    
    	cout << "1 - Spielfeld anzeigen\n";
    	cout << "2 - Feld besetzen\n";
    	cout << "3 - Felddaten anzeigen\n";
    	cout << "4 - Spielfeld loeschen\n";
    	cout << "5 - Programm beenden\n";
    
    	cin >> menue_eingabe;
    
    	switch (menue_eingabe)
    	{
    	case 1:
    		spielfeld_anzeigen();
    		break;
    	case 2:
    		feld_besetzen();
    		break;
    	case 3:
    		//felddaten;
    		break;
    	case 4:
    		//spielfeld_loeschen;
    		break;
    	case 5:
    		break;
    	default:
    		cout << "Falsche Eingabe. Programm wird beendet";
    	}
    
    	return 0;
    
    }
    */
    int spielfeld_anzeigen(void) {
    	for (int i = 0; i < 10; i++) {
    		for (int k = 0; k < 10; k++) {
    			if (spielfeld[i][k] == 0) {
    				cout << ".";
    			}
    			else {
    				cout << "X";
    			}
    		}
    		cout << "\n";
    	}
    	cout << "\n";
    	return 0;
    
    }
    
    int feld_besetzen(void) {
    	int xKoordinate = 0, yKoordinate = 0;
    	char name;
    
    	cout << "Auswahl: Land, Wasser, Luft, Lava\n";
    	cout << "x - Position (1-10): ";
    	cin >> xKoordinate;
    	cout << "y - Position (1-10): ";
    	cin >> yKoordinate;
    	cout << "Name: ";
    	cin >> name;
    
    	spielfeld[xKoordinate][yKoordinate] = name;
    
    	return 0;
    
    }
    


  • Eine Variable name vom Typ char hört sich falsch an. Oder soll ein Name tatsächlich aus nur einem Zeichen bestehen?

    Verwende std::string für Text.

    Wenn dein Buch dir stattdessen char Arrays beibringt: Buch => Papiertonne



  • Der Fehler ist etwas vertrackt.
    Mittels cin >> name wird nur ein einzelnes Zeichen eingelesen (da name als char deklariert ist). Bei Eingabe von "Luft" also nur das 'L'.
    Die restlichen Zeichen stehen jetzt noch im Eingabepuffer und werden dann in deiner Hauptschleife bei der menue_eingabe versucht auszulesen: da dies aber keine Zahlen sind, wird intern nur ein Fehlerflag gesetzt und die Schleife beginnt endlos von vorn ...

    Du solltest also name als int deklarieren und ersteinmal nur Zahlen eingeben (oder als std::string und zu einer Zahl konvertieren).

    s.a. Abfangen von falschen cin Eingaben?



  • Ah, Problem gelöst!

    Ich habe das Wissen über den Typ Char aus Standard C irgendwie total verdrängt...

    manni66 schrieb:

    Wenn dein Buch dir stattdessen char Arrays beibringt: Buch => Papiertonne

    So schlimm ist es nicht, war bloß mein Fehler 😃

    Es gibt sicher auch so etwas wie string - Arrays, oder? Also, dass ich ein Feld habe, in dem jeder Eintrag ein string ist. (eventuell mit variabler Größe?)

    Bisher reicht mir die Notlösung, die ich jetzt auf Grund eurer Vorschläge erstellt habe.

    int feld_besetzen(void) {
    	int xKoordinate = 0, yKoordinate = 0;
    	int name;
    
    	cout << "Auswahl: Land = 1, Wasser = 2, Luft = 3, Lava = 4\n";
    	cout << "x - Position (1-10): ";
    	cin >> xKoordinate;
    	cout << "y - Position (1-10): ";
    	cin >> yKoordinate;
    	cout << "Name: ";
    	cin >> name;
    	spielfeld[xKoordinate][yKoordinate] = name;
    
    	return 0;
    
    }
    

    Zumindest kann ich das Programm weiter schreiben.
    Dankeschön!



  • Zwecks Vollständigkeit der Unterfunktion:
    Die Indizes des Spielfeldes laufen von 0-9, aber es werden Eingaben von 1-10 gefordert für die Koordinaten.

    int feld_besetzen(void) {
    	int xKoordinate = 0, yKoordinate = 0;
    	int name;
    
    	cout << "Auswahl: Land = 1, Wasser = 2, Luft = 3, Lava = 4\n";
    	cout << "x - Position (1-10): ";
    	cin >> xKoordinate;
    	cout << "y - Position (1-10): ";
    	cin >> yKoordinate;
    	cout << "Name: ";
    	cin >> name;
    
    	xKoordinate = xKoordinate - 1; // Damit Eingaben von 1 - 10 erfolgen können
    	yKoordinate = yKoordinate - 1; // Damit Eingaben von 1 - 10 erfolgen können
    	spielfeld[xKoordinate][yKoordinate] = name;
    
    	return 0;
    
    }
    

    Vielleichts hilft es ja mal jemandem



  • Das wollte ich dir auch noch schreiben - werde wohl vergesslich...

    Du solltest aber dann auch dort die Eingaben überprüfen, ansonsten führt dein Programm zu undefiniertem Verhalten (UB), d.h. bestenfalls zu einem Absturz.


Log in to reply