(gelöst) Benutzereingabe "1" OK "1 a" nichtOK!



  • Hallo,
    Was kann ich tun, damit die Eingabe von z.B. "1 a" nicht als 1 akzeptiert wird?

    Gruß

    void MeineAuswahlFunktion()
    {
    	int Auswahl= 0;
    
    	for (Auswahl= 0; Auswahl< 4; Auswahl++)
    	{
    		fflush(stdin);
    		cin.clear();
    		cin >> Auswahl;
    		//Wenn jetzt "1 a" eingegeben wird, wird die Auswahl als 1 akzeptiert wird, was aber nicht sein sollte.
    		if (Auswahl!= 1 && Auswahl!= 2 && Auswahl!= 3 && Auswahl!= 4)
    		{
    			printf("Bitte nur Zahlen von 1 bis 4 eingeben: \n");
    			//Wenn z.B. eine 5 eingegeben wird, sollte eigentlich hier die Auswahl erneut abgefragt werden, was aber hier nicht passiert.
    			break;
    		}	
    	}
    		switch (Auswahl)
    		{
    		case 1:
    			// mach etwas
    			break;
    		case 2:
    		// mach etwas anderes
    			break;
    		case 3:
    		// mach etwas anderes
    			break;
    		case 4:
    		// mach etwas anderes
    			break;
    		}
    }
    


  • Wo ist das Problem, wenn "1 a" nicht als 1 akzeptiert wird? Es ist doch eine gültige 1!?
    So etwas zu realisieren ist übrigens schwieriger und aufgrund deines Mixes aus std::cin, printf, fflush(stdin)* und der Variablendeklaration ganz am Anfang der Funktion vermutlich zu hoch für dich.

    *Undefined Behavior. Dein Programm könnte auch "2" und "Hallo Welt!" als 1 akzeptieren. Oder deine Festplatte formatieren.



  • wie wäre es mit folgendem:

    int main()
    {
        bool quit = false;
        while (!quit)
        {
            cout << "Geben sie '1' ein, um das Programm zu beenden: ";
            string eingabe;
            getline(cin, eingabe);
            if (eingabe.size() != 0)
                quit = eingabe.size() == 1 && eingabe[0] == '1' ? true : false;
        }
    }
    


  • wennschon:

    #include <cctype>
    #include <limits>
    #include <iostream>
    #include <iomanip>
    
    bool only_whitespace( std::istream & is )
    {
    	std::istream::int_type ch;
    
    	while( std::isspace( ch = is.peek() ) && ch != '\n' && ch != EOF )
    		is.get();
    
    	return ch == '\n' || ch == EOF;
    }
    
    int main()
    {
    	int choice{};
    
    	do {
    		while( std::cout << "Input: ",
    		       !( std::cin >> std::skipws >> choice ) || !only_whitespace( std::cin ) || ( choice < 1 || 4 < choice ) ) {
    
    			std::cerr << "Input error!\n\n";
    			std::cin.clear();
    			std::cin.ignore( std::numeric_limits< std::streamsize >::max(), '\n' );
    		}
    
    		std::cout << choice << "\n\n";
    
    	} while( choice != 4 );
    }
    


  • Swordfish schrieb:

    int choice{};
    

    Machst du das immer so?



  • Ja. Blöde angewohnheit. Ich hab' wohl uniform-initialization zuuu erst genommen.



  • @ swordfish warum machst du das so kompliziert?

    bool status=false;
    std::string eingabe;
    
    cin >> eingabe;
    
    while(status==false)
    {
    
      if(strcmp(eingabe, "1")==0)
      {
        std::cout << "Hier wäre es jetzt 1-1" << std::endl;
        status=true;
      }
    
    }
    

    oder hab ich i.was falsch verstanden oder falsch gemacht? 😕

    lg



  • Nathan schrieb:

    Wo ist das Problem, wenn "1 a" nicht als 1 akzeptiert wird? Es ist doch eine gültige 1!?
    So etwas zu realisieren ist übrigens schwieriger und aufgrund deines Mixes aus std::cin, printf, fflush(stdin)* und der Variablendeklaration ganz am Anfang der Funktion vermutlich zu hoch für dich.

    *Undefined Behavior. Dein Programm könnte auch "2" und "Hallo Welt!" als 1 akzeptieren. Oder deine Festplatte formatieren.

    variablen am anfang der funktion sind doch normal?
    außer man hat tausende zeilen code aber ansonsten ist das meines wissens nach vollständig ok...
    so extrem lokal muss ja auch nich sein... das ist ja dann ab einem bestimmten punkt auch unübersichtlich und schlecht nachvollziehbar/ wartbar...

    also außer in manchen fällen wo es wirklich sinn macht, immer die variablen an den anfang der funktion!
    oder liege ich damit vollständig falsch?

    soweit ich weiß macht das auch keinen großen performance unterschied... außer vll in manchen spezialfäll (um die geht es mir abe rnicht) ...

    ist aber einfach besser anchvollziehbar und übersichtlicher -> was ja schon ein enormer vorteil wäre... 🙄 oder?



  • MfG schrieb:

    @ swordfish warum machst du das so kompliziert?

    Weiß nicht? Ist das kompliziert? Vielleich deshalb, weil sich dein Code so wie er dasteht nichtmal kompilieren lässt? Und selbst, wenn man deine Logikfehler ausbügelt:

    #include <iostream>
    #include <string>
    #include <cstring>
    
    int main()
    {
    	bool status=false;
    	std::string eingabe;
    
    	while(status==false)
    	{
    		std::cin >> eingabe;
    
    		if(std::strcmp(eingabe.c_str(), "1")==0)
    		{
    			std::cout << "Hier wäre es jetzt 1-1" << std::endl;
    			status=true;
    		}
    	}
    }
    

    geht "1 a" immer noch als gültige 1 durch.



  • Swordfish schrieb:

    MfG schrieb:

    @ swordfish warum machst du das so kompliziert?

    Weiß nicht? Ist das kompliziert? Vielleich deshalb, weil sich dein Code so wie er dasteht nichtmal kompilieren lässt? Und selbst, wenn man deine Logikfehler ausbügelt:

    #include <iostream>
    #include <string>
    #include <cstring>
    
    int main()
    {
    	bool status=false;
    	std::string eingabe;
     
    	while(status==false)
    	{
    		std::cin >> eingabe;
     
    		if(std::strcmp(eingabe.c_str(), "1")==0)
    		{
    			std::cout << "Hier wäre es jetzt 1-1" << std::endl;
    			status=true;
    		}
    	}
    }
    

    geht "1 a" immer noch als gültige 1 durch.

    sry war nur pseudo code hab gerade keine ide zur verfügung...
    hab ich nur halb herzig eben zur verdeutlich gecoded...

    strcmp ist kein mitglied von std 😉 ... also der code den du "verbessert" hast ist auch so nicht compilierbar...

    und mein beispiel funktioniert... da das was du feststellst an "cin" liegt... da "cin" die "eingabe" nach einem leerzeichen beendet...
    deswegen geht auch "1 a" durch da cin eh nur die 1 ein ließt 😉 ...

    siehe hier :

    #include <iostream>
    #include <string>
    #include <cstring>
    
    int main()
    {
        bool status=false;
        std::string eingabe;
    
        while(status==false)
        {
            std::cin >> eingabe;
    
            if(strcmp(eingabe.c_str(), "1")==0)
            {
                std::cout << "Hier wäre es jetzt 1-1" << std::endl;
                std::cout << eingabe.c_str();
                status=true;
            }else{
            	std::cout << "Bitte eine 1 eingeben!" << std::endl;
            }
        }
    }
    

    also es funktioniert schon... ! 😉
    falls man das umgehen will einfach cin durch getline austauschen 😉 ...
    ist jetzt auch genau so compilierbar und ausführbar... (c++11)

    ich fand schon das es relativ kompiliziert aussieht, du nicht?
    kann mich auch täuschen... deswegen frage ich ja mal... 🙄



  • um es nochmal zuverdeutlichen...:

    "cin" ließt bei einer eingabe von "1 a" nur die 1 in den string...
    da die eingabe nach einem leerzeichen von cin beendet wird...

    deswegen ist der vergleich auch richtig 😉 ... also vollständig korrekt...
    wenn man das umgehen will -> cin durch getline ersetzen...!



  • MfG schrieb:

    variablen am anfang der funktion sind doch normal?

    Ja, aber nur in C (weil man das dort so machen muss). In C++ definiert man alles so spät / lokal wie möglich.

    MfG schrieb:

    außer man hat tausende zeilen code aber ansonsten ist das meines wissens nach vollständig ok...

    Wer tausende Zeilen Code in einer einzigen Funktion hat sollte sich erstmal ganz andere Gedanken machen...

    MfG schrieb:

    so extrem lokal muss ja auch nich sein... das ist ja dann ab einem bestimmten punkt auch unübersichtlich und schlecht nachvollziehbar/ wartbar...

    Doch und ne. Aber alles am Anfang zu machen, das ist unübersichtlich und schlecht nachvollziehbar / wartbar.

    MfG schrieb:

    also außer in manchen fällen wo es wirklich sinn macht, immer die variablen an den anfang der funktion!

    Und was sind deiner Meinung nach diese Sonderfälle, bei welchen es Sinn macht?

    MfG schrieb:

    soweit ich weiß macht das auch keinen großen performance unterschied... außer vll in manchen spezialfäll (um die geht es mir abe rnicht) ...

    Oh nein, nicht schon wieder dieses Getrolle. Hab langsam die Nase voll von dieser Geschichte mit der Performance im Bezug auf die Reihenfolge der Variablendefinitionen. (siehe auch hier, scheint ein Running Gag zu sein...)

    MfG schrieb:

    sry war nur pseudo code hab gerade keine ide zur verfügung...

    Inwiefern hängt das zusammen?

    MfG schrieb:

    strcmp ist kein mitglied von std 😉 ... also der code den du "verbessert" hast ist auch so nicht compilierbar...

    Doch und doch. Alle C-Funktionen sind in der C++-Variante (aus den C++-Headern mit dem c-Präfix) im Namensbereich std . Siehe auch hier: http://en.cppreference.com/w/cpp/string/byte/strcmp



  • asfdlol schrieb:

    MfG schrieb:

    variablen am anfang der funktion sind doch normal?

    Ja, aber nur in C (weil man das dort so machen muss). In C++ definiert man alles so spät / lokal wie möglich.

    MfG schrieb:

    außer man hat tausende zeilen code aber ansonsten ist das meines wissens nach vollständig ok...

    Wer tausende Zeilen Code in einer einzigen Funktion hat sollte sich erstmal ganz andere Gedanken machen...

    MfG schrieb:

    so extrem lokal muss ja auch nich sein... das ist ja dann ab einem bestimmten punkt auch unübersichtlich und schlecht nachvollziehbar/ wartbar...

    Doch und ne. Aber alles am Anfang zu machen, das ist unübersichtlich und schlecht nachvollziehbar / wartbar.

    MfG schrieb:

    also außer in manchen fällen wo es wirklich sinn macht, immer die variablen an den anfang der funktion!

    Und was sind deiner Meinung nach diese Sonderfälle, bei welchen es Sinn macht?

    MfG schrieb:

    soweit ich weiß macht das auch keinen großen performance unterschied... außer vll in manchen spezialfäll (um die geht es mir abe rnicht) ...

    Oh nein, nicht schon wieder dieses Getrolle. Hab langsam die Nase voll von dieser Geschichte mit der Performance im Bezug auf die Reihenfolge der Variablendefinitionen. (siehe auch hier, scheint ein Running Gag zu sein...)

    MfG schrieb:

    sry war nur pseudo code hab gerade keine ide zur verfügung...

    Inwiefern hängt das zusammen?

    MfG schrieb:

    strcmp ist kein mitglied von std 😉 ... also der code den du "verbessert" hast ist auch so nicht compilierbar...

    Doch und doch. Alle C-Funktionen sind in der C++-Variante (aus den C++-Headern mit dem c-Präfix) im Namensbereich std . Siehe auch hier: http://en.cppreference.com/w/cpp/string/byte/strcmp

    ja das ist klar so spät wie möglich... doch hier macht es für mich nur sinn funktionsgebundene variablen lokal zu definieren... ich muss nicht meine variablen so deklarieren if(int x;x<100;x++)
    das führt in meinen augen bei großen projekten zu unübersichtlichkeit... aber ist wahrscheinlich geschmackssache... oder macht soetwas deutliche performance unterschiede?
    -> variablen also "Fast" so lokal wie möglich um einen ausgleich zwischen leserlichkeit und effektivität zuerhalten...

    ich meinte nich in der funktion sondern tausende zeilen code im ganzen projekt...

    ich deklariere dort meine variablen wo ich diese benötige (funktionsweise) aber ich fange nicht mit soertwas an weil das in meinen augen nix bring:
    if(int x;x<100;x++)
    vll macht soetwas in spezial fällen sinn aber bei 100 zeilen projektcode macht das das ganze einfach unübersichtlich für mich... ode rhat das performance vorteile die man nutzen sollte? wenn ja warum performance oder andere vorteile? (Quelle?)

    embedded-programmierung z.b. dort macht das sinn 😉 ... bzw. von dort kenn ich solchen c++ code... 🙄

    in dem thread steht aber das es keinne unterschied mach? also genau das was ich gesagt habe? -> ich trolle nicht... ich hab dem thread ersteller die frage beantwortet... falls ich doch i.wen beleidigt oder angegriffen habe war nicht meine absicht keines falls...

    hängt nicht zusammen wollte es nur mal sagen weil es ja hieß das der code nicht compiliert... hab ich gesagt das das zusammenhängt? 🙄

    @ fragesteller
    nochmal zur eigentlichen frage:
    hiermit kommt nur die eingabe von 1 2 3 oder 4 durch...

    #include <iostream>
    #include <string>
    #include <cstring>
    
    int main()
    {
        bool status=false;
        std::string eingabe;
    
        while(status==false)
        {
        	std::cout << "Bitte eine 1,2,3 oder 4 eingeben: "<< std::endl;
    
            getline(std::cin,eingabe);
    
            if(strcmp(eingabe.c_str(), "1")==0)
            {
                std::cout <<"Eingabe: " << eingabe.c_str() <<" --Erfolg, eine 1 eingeben!" << std::endl;
                status=true;
            }
    
            if(strcmp(eingabe.c_str(), "2")==0)
            {
                std::cout <<"Eingabe: " << eingabe.c_str() <<" --Erfolg, eine 2 eingeben!" << std::endl;
                status=true;
            }
    
            if(strcmp(eingabe.c_str(), "3")==0)
            {
                std::cout <<"Eingabe: " << eingabe.c_str() <<" --Erfolg, eine 3 eingeben!" << std::endl;
                status=true;
            }
    
            if(strcmp(eingabe.c_str(), "4")==0)
            {
                std::cout <<"Eingabe: " << eingabe.c_str() <<" --Erfolg, eine 4 eingeben!" << std::endl;
                status=true;
            }
    
            if(status==false)
            {
            	std::cout <<"Eingabe: " << eingabe.c_str() <<" --Fehler, Bitte eine 1,2,3,4 eingeben!" << std::endl;
            }
        }
    }
    


  • Bedenke, dass du nur eine while-Schleife benutzen kannst. Eine for-Schleife würde hier nicht funktionieren!



  • MarkusMundM schrieb:

    Bedenke, dass du nur eine while-Schleife benutzen kannst. Eine for-Schleife würde hier nicht funktionieren!

    Doch, klar. while(foo) kann man immer auch for(;foo;) schreiben. Es ändert sich gar nichts.



  • MfG schrieb:

    "cin" ließt bei einer eingabe von "1 a" nur die 1 in den string...
    da die eingabe nach einem leerzeichen von cin beendet wird...

    Ja. Und wenn du nochmal beim OP nachschaust, dann wirst du merken, daß dieses Verhalten eben nicht gewünscht ist.



  • Swordfish schrieb:

    MfG schrieb:

    "cin" ließt bei einer eingabe von "1 a" nur die 1 in den string...
    da die eingabe nach einem leerzeichen von cin beendet wird...

    Ja. Und wenn du nochmal beim OP nachschaust, dann wirst du merken, daß dieses Verhalten eben nicht gewünscht ist.

    und wenn du mal mein text ordentlich ließt wirst du sehen das mein zu letzt gepostet beispiel sich NICHT so verhält...
    da ich getline nutze ... 🙄

    lg



  • nachtrag:

    dieses verhalten entsteht dadurch das std::cin die eingabe nach einem leerzeichen nicht mehr "ließt/erkennt"...
    deswegen ist "1 a" auch -> 1
    wenn du "1a" bei std::cin eingibst dann klappt das auch mit cin...! 😉

    bei getline() ist dies nicht der fall deswegen tritt dort das verhalten nicht auf... 😉

    lg



  • oenone schrieb:

    MarkusMundM schrieb:

    Bedenke, dass du nur eine while-Schleife benutzen kannst. Eine for-Schleife würde hier nicht funktionieren!

    Doch, klar. while(foo) kann man immer auch for(;foo;) schreiben. Es ändert sich gar nichts.

    Nein, da MfG eine bool Variable verwendet.
    for(;bChoiceState == false;) !! 👎



  • Ich halte Zeilenweise in einen String lesen und dann auseinanderfriemeln trotzdem für eine bescheidene Lösung. Was machst denn, wenn der integer mehrstellig wird? Viel Spaß!

    @ MarkusMundM: Hunger? Fang: <°)(((><


Anmelden zum Antworten