Fehler nur wo und warum??



  • Du musst mit diesen "Streams" immer etwas aufpassen, d.h. beachten welche Konsequenzen die Eingaben haben könnten.

    In deinem Fall bleibt nach dem cin >> D noch ein '\n' Zeichen im Stream, welches auch durch das get() nicht entfernt wird. In der do-while Schleife geht der Stream dann in einen Fehlerzustand, weil cin ein Integerwert erwartet aber durch das immer noch vorhandene '\n'-Zeichen keinen findet. Da du die Schleife erst beendest, wenn ein gültiger Wert (1 oder 2) eingegeben wurde ensteht das Chaos.

    Das '\n' Zeichen bekommst du ebenfalls mit einem cin.ignore() weg. Also:

    //...
    int D;
    cin >> D;
    cin.ignore ();
    //...
    


  • OK, war zu spät. 🙂


  • Mod

    Ich habe es mir mal angeschaut. Allgemein: Tu dir selbst einen großen Gefallen und nimm string anstatt char-Arrays.

    Dein Problem liegt an der Mischung von formatierten Eingabeoperationen (Operator >>) und unformatierten Eingaben (get). Die beiden Methoden vertragen sich nicht so gut. Wenn nämlich am Anfang eine Zahl mit cin >> D eingelesen wird, dann wird deren Eingabe üblicherweise mit der Eingabetaste abgeschlossen. Der Operator >> liest dann die Zahl von der Eingabe, lässt aber das Zeilenendzeichen noch da. Bei der nächsten Benutzung von >> würden führende Zeilenendzeichen dann einfach ignoriert, so dass dies kein Problem ist. Deine nächste Eingabeoperation ist aber eine unformatierte Eingabe: get. Dem macht das schon etwas aus, denn es liest bis zum nächsten Zeilenendzeichen ein. Dies ist nun aber direkt das nächste Zeichen. Das heißt es wird gar nichts eingelesen!
    Und nun guckt man in die Referenz von get und sieht, dass im Falle, dass nichts gelesen wird, das failbit des Streams (cin) gesetzt wird, um diesen Fehler anzuzeigen. Solange aber der Stream im Fehlerzustand ist, kann nichts weiter eingelesen werden, alle Eingabeoperationen schlagen automatisch fehl. Das heißt in deiner darauf folgenden Schleife zur Teamabfrage wird der Wert von SpielerListe[i].Team nie geändert. Und da die Schleife so lange läuft bis der Wert 1 oder 2 ist, läuft sie ewig weiter. Und das ist es was du siehst.

    Abhilfe: Du könntest nur formatierte Eingaben verwenden, also auch bei der eingabe des Spielernamens. Der Nachteil ist, dass du dann nur Namen ohne Leerzeichen eingeben könntest (weil der Operator >> beim Erreichen von Whitespace die Eingabe als Beendet ansieht).
    Noch eine Alternative wäre, immer nur unformatierte Eingabeoperationen zu benuzten (aber bitte getline aus dem string-Header, nicht get.). Der Nachteil hier wäre, dass du die Zahlen hinterher noch mühsam aus der eingegebenen Zeile extrahieren müsstest, was ich nicht anraten würde.
    Und die letzte und wohl auch beste Alternative die mir gerade einfällt: Bevor du get (oder besser getline) benutzt, guckst du ob das nächste Zeichen im Stream (peek()) ein Zeilenendzeichen ('\n') ist. Wenn es eines ist, benutzt du ignore(), um es zu überspringen.

    edit: Viel zu spät. Kein Wunder, ich habe ja auch einen kleinen Roman geschrieben 😃



  • Irgendwie scheint mein Gesülze nicht recht zu stimmen. Denn zwei hintereinder ausgeführte cin >> D würden ja auch funktionieren. Hab aber jetzt keine Lust nochmal über dieses Streamzeug nachzudenken. 😞



  • SeppJ schrieb:

    edit: Viel zu spät. Kein Wunder, ich habe ja auch einen kleinen Roman geschrieben 😃

    Danke für den Hinweis auf die Entfernung der führenden Zeilenendezeichen in deinem Roman. Da ist mir doch glatt wieder ein Licht aufgegangen. 🙂



  • wie kann ich das denn nachgucken "guckst du ob das nächste Zeichen im Stream (peek()) ein Zeilenendzeichen ('\n')"
    tut mir leid wenn das eine dumme frage ist 😃

    achja und schonmal danke an alle 🙂


  • Mod

    MaikBae schrieb:

    wie kann ich das denn nachgucken "guckst du ob das nächste Zeichen im Stream (peek()) ein Zeilenendzeichen ('\n')"
    tut mir leid wenn das eine dumme frage ist 😃

    achja und schonmal danke an alle 🙂

    if (cin.peek() == '\n')  // ...
    

    😃



  • Nun habe ich nochmal ein Problem 😃
    folgendes also bei dem "\n" Problem war cin.peek() = 10
    und dann konnte man das immer mit cin.ignore() wieder loeschen
    aber jetzt ist cin.peek() = -1 und nach cin.ignore() ist das immer noch -1 gibt es noch eine möglichkeit das wieder zurückzusetzen?

    Ich hoffe ihr konntet mir folgen :p



  • Du bekommst EOF angezeigt.

    http://www.cplusplus.com/reference/iostream/istream/peek/

    Mit cin.clear() wird das Objekt cin wieder eingabebereit.

    http://www.cplusplus.com/reference/iostream/ios/clear/



  • Du bekommst EOF angezeigt.

    http://www.cplusplus.com/reference/iostream/istream/peek/

    Mit cin.clear() wird das Objekt cin wieder eingabebereit.

    http://www.cplusplus.com/reference/iostream/ios/clear/



  • ok danke jetzt sind alle fragen von mir beantwortet 🙂


Anmelden zum Antworten