Programm "spinnt" bei Buchstaben-Eingabe! Wer hat die Lösung??



  • while ( zahl < '1' || zahl > '0' )

    Wie soll denn das funktionieren??????



  • Gemeint war wohl:

    while ( zahl < '0' || zahl > '9' )
    

    Soll heissen, while(keine Zahlen eingegeben){neue lesen}

    Jockel



  • Die Bedingungen sollen sein:

    - wenn zahl nicht zwischen 1 und 10 -> fehler
    - alle anderen eingaben -> fehler

    Das geht ja mit eurem Vorschlag nicht....oder sehe ich das falsch?



  • uwe_o schrieb:

    ....oder sehe ich das falsch?

    Nee, siehst du richtg.
    Ich hab auch gar nicht richtig hingeschaut.
    Bei meinem Post ging's nur um das Erkennen von Zahlen als Eingabe
    bei char.

    Für dein Problem weis ich's jetzt auch nicht auswendig.
    Lies am besten in einen String, suche nach einer 'isDigit'-Funktion
    und caste bei Errfolg in int.

    Jockel



  • Hier ein Lösungsbeispiel:

    #include <iostream>
    #include <cstring>
    #include <cctype>
    #include <cmath>
    
    using namespace std;
    
    bool parseInt(const char* s, int& num)
    {
    	size_t i,n=strlen(s);
    	num=0;
    
    	for(i=0;i<n;i++)
    		if(isdigit(s[i]))
    			num += ((s[i]-'0')*pow(10,n-i-1));
    		else
    		{
    			cout<<"Fehler bei der Interpretation als Ganzzahl: "<<s[i]<<" ist keine Ziffer!"<<endl;
    			return false;
    		}	
    	return true;
    }
    
    int main()
    {
    	int zahl;
    	char buf[255];
    
    	do
        {
            system("cls");
            cout<<"Geben Sie eine Zahl ein: ";
            cin>>buf;
    
    		if(!parseInt(buf,zahl))
    			break;
    
            if(zahl<1 || zahl>10)cout<<"Fehler!";
        }
        while(zahl>=1 && zahl<=10); 
    }
    


  • #include <cctype> //kann weg
    


  • Das Problem ist, dass 1. der Stream bei einem fehlgeschlagenen Leseversuch entsprechende Errorflags setzt und das Lesen verweigert, bis das bereinigt wurde und 2. dass du den Kram noch im Stream drin stehen hast. Am sichersten kriegt man das über eine gebufferte Eingabe hin, also:

    #include <iostream>
    #include <string>
    #include <sstream>
    
    int main() {
      int zahl;
    
      do {
        std::string zeile;
    
        std::cout << "Zahl zwischen 1 und 10 eingeben: " << std::flush;
        std::getline(std::cin, zeile);
    
        if(!cin) {
          std::cerr << "Whoops. Irgendwas ist gründlich schief gegangen. Das hier sollte nicht passieren." << std::endl;
          return -1;
        }
    
        std::stringstream sin(zeile);
        sin >> zahl;
      } while(zahl < 1 || zahl > 10);
    
      std::cout << "Eingegeben wurde: " << zahl << std::endl;
    }
    


  • Hum. Besser wär eigentlich noch:

    #include <iostream>
    #include <string>
    #include <sstream>
    
    int main() {
      int zahl;
      std::stringstream sin;
    
      do {
        std::string zeile;
    
        std::cout << "Zahl zwischen 1 und 10 eingeben: " << std::flush;
        std::getline(std::cin, zeile);
    
        if(!cin) {
          std::cerr << "Whoops. Irgendwas ist gründlich schief gegangen. Das hier sollte nicht passieren." << std::endl;
          return -1;
        }
    
        sin.clear();    // Fehlerflags auf "Alles OK" setzen
        sin.str(zeile); // Gerade eingelesene Zeile in den Buffer packen
        sin >> zahl;    // Buffer in Zahl parsen
      } while(!sin /* Wenn beim parsen was schief geht, ist !sin wahr */ || zahl < 1 || zahl > 10);
    
      std::cout << "Eingegeben wurde: " << zahl << std::endl;
    }
    


  • if(!cin) {
          std::cerr << "Whoops. Irgendwas ist gründlich schief gegangen. Das hier sollte nicht passieren." << std::endl;
          return -1;
        }
    

    ist natürlch

    if(!std::cin) {
          std::cerr << "Whoops. Irgendwas ist gründlich schief gegangen. Das hier sollte nicht passieren." << std::endl;
          return -1;
        }
    

    aber das sollte schon kla sein denke ich



  • Ich habe das mal getestet, optimal läuft das immernoch nicht!

    Was mir aufgefallen ist:

    - zu Beginn muss man zweimal etwas eingeben, damit das Programm reagiert
    - bei Buchstaben-Eingabe kommt keine Fehlermeldung
    - wenn ich z.B. "1" eingebe, muss ich danach noch etwas angeben, damit die "1" gewertet wird

    Ich habe keine Ahnung von dem Quelltext, ich wollte es nur mal anmerken....ihr nehmts mir hoffentlich nicht übel 🙂



  • Anmerker schrieb:

    - zu Beginn muss man zweimal etwas eingeben, damit das Programm reagiert

    Kann ich hier (Linux-Kernel 2.6.8 m. Debian-patches, gcc 3.4.2) nicht nachvollziehen.

    Anmerker schrieb:

    - bei Buchstaben-Eingabe kommt keine Fehlermeldung

    Richtig, wenn eine Fehlermeldung kommen soll, halt was in der Art:

    for(;;) {
      //...
      if(!sin || zahl < 1  || zahl > 10) std::cerr << "Ne Zahl zwischen 1 und 10, du Depp!" << std::endl;
      else break;
    }
    

    Go figure.

    Anmerker schrieb:

    - wenn ich z.B. "1" eingebe, muss ich danach noch etwas angeben, damit die "1" gewertet wird

    Kann ich hier ebenfalls nicht nachvollziehen.



  • Also ich habe extra ein Projekt erstellt und es mal getestet!

    1. ich führe das Programm aus
    2. gebe "1" ein und drücke enter
    3. der kursor springt in die nächste zeile
    4. drücke enter oder drücke taste+enter
    5. es erscheint "eingegeben wurde: 1"

    Die Punkter 3+4 sollte es aber nicht geben oder?

    Wenn ich bei Punkt 2 einen Buchstaben eingebe, sollte eine Fehlermeldung erscheinen! Das passiert nicht! Es passiert das gleiche wie in Punkt 3+4 beschrieben! Bei Punkt 5 erscheint "Zahl zwischen 1 und 10 eingeben: "!

    Die Punkte 3+4 sollte es also bei beiden Szenarios nicht geben!

    @ 0xdeadbeef
    Bei deinem Vorschlag wird die Fehlermeldung in einer Endlos-Schleife ausgegeben! Wenn ich die for-Schleife wegnehme, kommt die Fehlermeldung bei jeder Eingabe!!

    Also wie gesagt, ich wüsste nicht wies besser geht....wollte euch nur darauf hinweisen! 🙂



  • Ich danke euch für eure Bemühungen, aber ich werd mir wohl was anderes überlegen...bei mir funktioniert das auch nicht so ganz!!

    Nochmal Danke!



  • Punkte 3+4 gibt es nicht, zumindest kann ich sie hier nicht nachvollziehen. Und die for-schleife sollte die do { ... } while(...)-Schleife ersetzen, nicht zusätzlich rein geschrieben werden.



  • Also ich muss zu Beginn auch 2mal was eingeben, bevor was passiert! Das mit der for-Schleife funktioniert bei mir!


Anmelden zum Antworten