cin Puffer Problem

Sadakazu

Well-Known Member
Habs im anderen Thread ja schon angesprochen.....
Hab die ganze Kiste mal eben nachbauen können....
Bevor ihr den Code euch anguckt... JAHAAA ich weiß if else if else if else ist extrem unschön.... darum gehts auch nicht.... ^^

Code:
#include <iostream>
#include <sstream>

void listener();
void execute(std::string[]);
void setUser(std::string, int, float);

int main() {

   std::cout << "Mein Program Bla Blub" << std::endl;


   listener();

   return 0;
}

void listener() {

   std::cout << "> ";
   std::string cmd[3];
   std::string line;
   getline(std::cin, line);  // get the entire line
   std::istringstream stream(line);
  for (int i=0; stream.good(); i++) {
  stream >> cmd[i];
  }

   execute(cmd);
}

void execute(std::string cmd[]) {

   if(cmd[0] == "test") {
     std::cout << "du hast " << cmd[0] << " eingegeben" << std::endl;
   } else if (cmd[0] == "bla") {
     if(cmd[1] == "blub") {
       std::string name;
       int age;
       float height;

       std::cout << "Name eingeben: ";
       std::cin >> name;
       std::cout << "\nAlter eingeben: ";
       std::cin >> age;
       std::cout << "\nGröße eingeben: ";
       std::cin >> height;

       setUser(name, age, height);

     } else {
       std::cout << "Du vogel hast blub vergessen!" << std::endl;
     }
   } else {
     std::cout << "Hä? nix verstehen!" << std::endl;
   }

   listener();
}

void setUser(std::string aString, int bInt, float cFloat) {
   std::cout << "Name: " << aString << std::endl;
   std::cout << "Alter: " << bInt << std::endl;
   std::cout << "Gröpe: " << cFloat << std::endl;
   std::cout << "sehr interessant... ende setUser()" << std::endl;
}
So mein Problem hier.... bla blub wird eingegeben.... ich soll was eingeben, nach der eingabe wird eine andere Funktion aufgerufen die die übergebenen werte einfach nur ausgibt.... danach spring ich ja zurück... die if verzweitung wird beendet und das nächste auf der liste wäre listener(); ... da springt er rein.. führt direkt ein leeres kommand aus ich lande bei execute() in der else verzweigung und bekomme 1x ein hä? nix verstehen zurück.... dannach springt er wieder in listener(); rein und alles ist tutti...

Ausgabe:
Code:
[sada@arch Debug]$ ./codetests
Mein Program Bla Blub
> bla blub
Name eingeben: Test

Alter eingeben: 123

Größe eingeben: 435.45
Name: Test
Alter: 123
Gröpe: 435.45
sehr interessant... ende setUser()
> Hä? nix verstehen!
>

Das Problem lässt sich vermutlich umgehen indem ich einfach eine Funktion schreibe die sich um die Eingabe kümmernt, bzw die Eingabe entgegen nimmt und dann an setUser() weiter leitet....

Trotzdem würd ich gern wissen, warum cin.clear(); und cin.sync(); nix bewirken.... egal wo ich sie hin setzte.... nach bla blub wird der listener 2x ausgeführt bzw einmal eine leere eingabe übermittelt....

[EDIT]
Nein das problem lässt sich nicht beheben indem ich ne getUser() funktion schreibe...
Und auch ganz egal wo ich cin.clear(); cin.sync setzte.... es wird immer einmal ein leeres command ausgegeben....

Der Hinweis mit dem Puffer kam überigns noch aus dem anderen Forum, bevor ich einen ähnlichen code gepostet hatte und den netten Hinweis ich soll das progammieren an den Nagel hängen ich hätte keine ahnung und wäre nicht bereit bücher zu lesen und google zu benutzen ;) ^^
 
Zuletzt bearbeitet:
Ach son mist.... man kann hier ja nicht nach ner Zeit editieren.....
Nachdem ich jetzt nochmal gefühlt 2 Stunden rumgepopelt hab und nach gefühlt 20 Youtube Videos und 500 durchwühlten Google treffern.... hab ich endlich die Lösung gefunden -.-"

Code:
[schnipp]
getUser();
[schnipp]
void getUser() {
   std::string name;
   int age;
   float height;

   std::cout << "Name eingeben: ";
   std::cin >> name;
   std::cout << "\nAlter eingeben: ";
   std::cin >> age;
   std::cout << "\nGröße eingeben: ";
   std::cin >> height;
   setUser(name, age, height);
   
   // Hier meine Lösung!
   std::cin.ignore();
}

Aber warum ignore? ich dachte clear() löscht den Puffer?
 
In Deiner ersten Lösung war das Problem, dass Du über das Ende von cmd hinaus schreiben konntest. Und das lief halt so lange bis Du mit CTRL+D den Input geschlossen hast oder das Programm halt irgendwann abstürzt. Ich rede hier von der Funktion listener().
 
Das Problem ist die listen() Funktion die noch aufgerufen wird. Mit dem ignore verhindert er dass die weiter von stdin liest und in ihr Undefined behaviour läuft.
 
Der Quelltext wurde von irgendwo her kopiert, mit eigenen Bruchstücken ergänzt, ohne wirklich zu wissen was sich da abspielt. Das bringt nichts, und das wird nie etwas bringen.

Hier ist ein kleines Beispielprogramm, kauf Dir ein Einsteigerbuch, damit Du das nachvollziehen kannst. Und am besten schreibst Du es ab, nicht kopieren. Auch durch Abschreiben von Quelltext lernt man, vor allen Dingen, was man alles für Fehler machen kann, und wie die Reaktion des Compilers darauf ist.

Code:
//Beispiel C++-Programm für Ein- und Ausgabe, 8. April 2017

#include <iostream>
#include <iomanip>   //Für setw() oder width(int)
#include <string>
using namespace std;

int main(void)
{
    string bezeichnung;
    double listenpreis, gesamtpreis;
    double mehrwertsteuer = 11.75;
   
    //Hier: MINI COOPER S CABRIO
    cout << "\n";
    cout << "Geben Sie ihr Wunschauto ein: ";
   
    //Höchstens 22 Zeichen
    cin.width(22);
    cin >> bezeichnung;
    cin.sync();  //Puffer leeren
   
    cout << "\nGeben Sie den Listenpreis ein: ";
    cin >> listenpreis;
   
    gesamtpreis = (listenpreis + ((listenpreis / 100) * mehrwertsteuer));
   
    cout << "\n\nDer Gesamtpreis samt 11,75% Mehrwertsteuer betraegt: ";
   
    //Festpunktzahl - 2 Nachkommastellen - Feldbreite
    cout << fixed << setprecision(2) << setw(6) << gesamtpreis << " Euro";
    cout << endl;
   
    return(0);
}

Beispiel:
Autokauf-C++.jpg
 
Zurück
Oben