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



  • Was rede ich denn. Doch das geht natürlich. Sorry, ich war doof!



  • Swordfish schrieb:

    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: <°)(((><

    ich habe keinen intger im code... 😕
    sondern ein string und ein stringcompare...
    da ist egal was drinn steht...
    entweder es ist identisch == 0 oder es ist das nicht...
    also was für ein intger meinst du? 🙄

    zu mal das auch nicht die frage vom threadersteller war... 😃
    na ja egal ... ich muss mich hier nicht verteidigen... verstehe eig gar nicht was du meinen code andauernd in fragestellst aber noch nicht mal richtig liest?!



  • ps. auch das zeilenweise einlesen ist in diesem fall ok...
    denn ich "firemel" dort nix auseinander...
    bitte schau ich nutze strcmp... das ist ein vergleich...!!
    (kein RegEx oder soetwas... bitte nicht verwechseln... )



  • MfG schrieb:

    ich muss mich hier nicht verteidigen... verstehe eig gar nicht was du meinen code andauernd in fragestellst aber noch nicht mal richtig liest?!

    Obwohl ich immer noch denke, dass du bloss trollst und dich dumm stellst:
    Mehrere Leute haben dich auf elementare Fehler / Unschönheiten im Code aufmerksam gemacht, was du getrost ignoriert hast und für mich liest er sich so, als wäre er von einem blutigen Anfänger geschrieben worden ( strcmp(eingabe.c_str(), [...] , std::cout << [...] eingabe.c_str() [...] oder dass du vier Mal denselben Code im Programm hast und nicht auf die Idee kommst, eine Funktion oder eine Schleife daraus zu machen (von den Logikfehlern mal abgesehen)). Ein gutes Grundlagenbuch zu besorgen und es durchzuarbeiten würde bestimmt nicht schaden.

    Und auch für dich gibt's etwas Leckeres: ><(((°>



  • asfdlol schrieb:

    MfG schrieb:

    ich muss mich hier nicht verteidigen... verstehe eig gar nicht was du meinen code andauernd in fragestellst aber noch nicht mal richtig liest?!

    Obwohl ich immer noch denke, dass du bloss trollst und dich dumm stellst:
    Mehrere Leute haben dich auf elementare Fehler / Unschönheiten im Code aufmerksam gemacht, was du getrost ignoriert hast und für mich liest er sich so, als wäre er von einem blutigen Anfänger geschrieben worden ( strcmp(eingabe.c_str(), [...] , std::cout << [...] eingabe.c_str() [...] oder dass du vier Mal denselben Code im Programm hast und nicht auf die Idee kommst, eine Funktion oder eine Schleife daraus zu machen (von den Logikfehlern mal abgesehen)). Ein gutes Grundlagenbuch zu besorgen und es durchzuarbeiten würde bestimmt nicht schaden.

    Und auch für dich gibt's etwas Leckeres: ><(((°>

    ? ich nutze gar keinen intger in dem code... deswegen kann da auch nix 2 stellig werden...
    weiter fehler waren? ich kann mich eig an nix erinnern?
    -> Marcus das ich aus while keine for schleife machen kann...
    dafrage ich mich erstmal... die aufgabe war 1,2,3 und 4 einizig als eingabe zuzulassen... das tut mein code...
    weiß nicht wenn man die konkrekte aufgabenstellung mit einbezieht... wo wären dann noch verbesserungen? das würde mich jtzt mal interessieren ... denn diese unschönheiten existieren ja gar nicht in meinem zu letzt geposteten beispiel...

    wo sind denn in meinem code elementare fehler? (bis auf das argument mit der funktion... )

    🙄 ok mit der funktion hast du recht... hab ich auch schon bereut... aber das hat ja noch nichmal einer gesagt...
    (aber i.was von intger obwohl ich nict mal eine im code hab? -> aber wahrscheinlich ein schönheitsfehler... 😃 )

    lol ein einfacher code heißt nicht das ich ein anfänger bin...
    aber eig sollte es doch das ziel sein ein komplexes problem so einfach wie möglich zu lösen oder siehst du das anders?
    und es geht auch nicht immer um performance und wer hat die komplizierteste funktion benutzt... mein code ist übersichtlich und leserlich... wartbar auch in 30 jahre... weil du in 1 blick siehst was dort passiert... (also ich zumindest)

    und wo sollte ich denn da eine schleife nutzen? ich hab doch eine...? 😕

    und was für logikfehler...?

    ich lerne auch immer was dazu... aber außer das man noch eine funktion draus machen kann, was ich nicht gemacht habe aus zeitgründen...
    außerdem hab ich ja auch nie behauptet der code ist perfekt... 😉

    aber "logikfehler" und "elementare fehler" in meinem zuletzt geposten code würden mich wirklich mal interessieren...? 😕



  • hier übrigens auch was für dich 😉 ...

    <(((°> && ><(((°>



  • sry edit geht nicht...

    aber ich trolle auch nicht! ich wollte nur helfen...
    und ganz ehrlich ärgere ich mich schon darüber...

    hätte er halt das "eierlegendewollmilchmonster" von Swordfish genommen...
    mir ist das egal...

    aber ich hab nicht gerne unnötigen code der das ganze auch noch in meinen augen im nachhinein (nach 1-10 jahren) nicht mehr nachvollziehbar macht ode rnur mit soviel aufwand das du es neu coden kannst... 😉

    der code muss nicht "immer" in jeder "lage" auch in welchen in die er evt. nie kommt funktionieren...
    sondern nur alles was realistisch passieren kann behandeln und sie niemals undefiniert verhalten 😉 ...

    warum einfach wenns auch kompiliziert geht ... oder? 🙄



  • Ich danke euch vielmals für eure Hilfe.
    @Swordfish, deine Lösung macht genau das, was ich haben möchte, (Dass die Eingabe von "Leerzeichen" + 1 immer noch als 1 akzeptiert wird, spielt keine Rolle.)
    nämlich eine Funktion, mit der eine Benutzereingabe nur von 1,2,3 oder 4 in einer Schleife akzeptiert wird und mit der Eingabe von 4 das Programm beendet wird.
    Perfekt! Aber ich verstehe es nicht! Ein paar Kommentare wären für mich als Anfänger sehr hilfreich, womit ich in aller Bescheidenheit keine falsche Erwartung zeigen möchte.

    @MfG,deine Lösung ist für mich als Anfänger verständlich und so aufgebaut, dass ich jeden Schritt nachvollziehen kann. Ich hätte noch erwähnen sollen, was die Funktion machen soll.
    Dass die Eingabe von nur 1, 2, 3 oder 4 möglich sein soll, hast du prima gelöst. Darüber hinaus möchte ich, dass mit der Eingabe von 4 das Programm beendet wird, bei den Zahlen 1,2,3 aber die Schleife durchläuft und andere Aufgaben erfüllt werden.

    @asfdlol, vielen Dank für deine Unterstützung!

    @oenone & MarkusM&M, ich versuche immer eine for schleife zu verwenden, da ich sie übersichtlicher finde, als while oder do-while.

    Schöne Grüße



  • b1419589 schrieb:

    Ich danke euch vielmals für eure Hilfe.
    @Swordfish, deine Lösung macht genau das, was ich haben möchte, (Dass die Eingabe von "Leerzeichen" + 1 immer noch als 1 akzeptiert wird, spielt keine Rolle.)
    nämlich eine Funktion, mit der eine Benutzereingabe nur von 1,2,3 oder 4 in einer Schleife akzeptiert wird und mit der Eingabe von 4 das Programm beendet wird.
    Perfekt! Aber ich verstehe es nicht! Ein paar Kommentare wären für mich als Anfänger sehr hilfreich, womit ich in aller Bescheidenheit keine falsche Erwartung zeigen möchte.

    @MfG,deine Lösung ist für mich als Anfänger verständlich und so aufgebaut, dass ich jeden Schritt nachvollziehen kann. Ich hätte noch erwähnen sollen, was die Funktion machen soll.
    Dass die Eingabe von nur 1, 2, 3 oder 4 möglich sein soll, hast du prima gelöst. Darüber hinaus möchte ich, dass mit der Eingabe von 4 das Programm beendet wird, bei den Zahlen 1,2,3 aber die Schleife durchläuft und andere Aufgaben erfüllt werden.

    @asfdlol, vielen Dank für deine Unterstützung!

    @oenone & MarkusM&M, ich versuche immer eine for schleife zu verwenden, da ich sie übersichtlicher finde, als while oder do-while.

    Schöne Grüße

    ok dann hat es wenigstens sinn gemacht... 🙂
    freut mich das du dein problem lösen konntest...

    ich wollte dir mit meinem beispiel genau auf einfache und verständliche weise das nahe bringen... 😉
    freut mich wenn du es verstanden hast und nachvollziehen konntest...
    das war ja das worum es ging, aber es kann an meinem code noch viel/bzw. das was du genau benötigst optimiert werden... (wie meine vorredner schon erwähnt haebn)



  • b1419589 schrieb:

    Ich danke euch vielmals für eure Hilfe.
    @Swordfish, deine Lösung macht genau das, was ich haben möchte, (Dass die Eingabe von "Leerzeichen" + 1 immer noch als 1 akzeptiert wird, spielt keine Rolle.)
    nämlich eine Funktion, mit der eine Benutzereingabe nur von 1,2,3 oder 4 in einer Schleife akzeptiert wird und mit der Eingabe von 4 das Programm beendet wird.
    Perfekt! Aber ich verstehe es nicht! Ein paar Kommentare wären für mich als Anfänger sehr hilfreich, womit ich in aller Bescheidenheit keine falsche Erwartung zeigen möchte.

    #include <cctype>    // std::isspace()
    #include <limits>    // std::numeric_limits<>::max()
    #include <iomanip>   // std::noskipws()
    #include <iostream>
    
    bool only_whitespace( std::istream & is )       // true, wenn nur white-space Zeichen in is sind.
    {										        
        std::istream::int_type ch = 0;
    
    	// solange das naechste Zeichen in is
    
    	while( ch != '\n' && ch != EOF              // kein Newline ist und auch das Streamende nicht erreicht ist
    	       && std::isspace( ch = is.peek() )    // und ein Leerzeichen, Tab, ... ist (peek() nur ansehen, nicht extrahieren)
    	)									        
    	{									        
            is.get();                               // extrahiere das Zeichen aus is (= werfe das angesehene Zeichen weg).
    	}
    
        return ch == '\n' || ch == EOF;             // ist die while()-Schleife wegen '\n' oder EOF abgebrochen?
    	                                            // wenn nicht, war es ein anderes Zeichen das nicht isspace() ist.
    }
    
    int main()
    {
        int choice;
    
        do {
    		// solange
    
    		while( std::cout << "Input: ",
                   !( std::cin >> std::noskipws >> choice )  // der Extraktionsversuch eines Integers aus cin fehlschlaegt   
    		       || !only_whitespace( std::cin )  // oder nach dem Extraktionsversuch noch weitere Zeichen auszer white-space in cin stehen
    		       || ( choice < 1 || 4 < choice )  // oder das gelesene choice nicht in 1...4 liegt
    		)
    		{
                std::cerr << "Input error!\n\n";    // eine Fehlermeldung ausgeben
                std::cin.clear();                   // Fehlerflags loeschen, falls der Extraktionsversuch fehlgeschlagen ist
    
    			std::cin.ignore(                    // weitere Zeichen in cin ignorieren
    				std::numeric_limits< std::streamsize >::max(), // Anzahl zu ignorierender Zeichen, vorsichtshalber die groesztmoegliche Anzahl annehmen
    				'\n'                            // solange kein '\n' daherkommt
    			);
            }
    
            std::cout << choice << "\n\n";          // getroffene Auswahl ausgeben
    
        } while( choice != 4 );
    }
    


  • b1419589 schrieb:

    [...] (Dass die Eingabe von "Leerzeichen" + 1 immer noch als 1 akzeptiert wird, spielt keine Rolle.) [...]

    Gefixt. Hatte im Original fälschlicherweise std::skipws statt richtig std::noskipws .



  • @Swordfish, dankeschön! Alles perfekt! Damit wurden alle meine Probleme gelöst und Fragen beantwortet.



  • #include <cctype>    // std::isspace()
    #include <limits>    // std::numeric_limits<>::max()
    #include <iomanip>   // std::noskipws()
    #include <iostream>
    
    bool only_whitespace(std::istream & is)       // true, wenn nur white-space Zeichen in is sind.
    {
    	std::istream::int_type ch = 0;
    
    	// solange das naechste Zeichen in is
    
    	while (ch != '\n' && ch != EOF              // kein Newline ist und auch das Streamende nicht erreicht ist
    		&& std::isspace(ch = is.peek())    // und ein Leerzeichen, Tab, ... ist (peek() nur ansehen, nicht extrahieren)
    		)
    	{
    		is.get();                               // extrahiere das Zeichen aus is (= werfe das angesehene Zeichen weg).
    	}
    
    	return ch == '\n' || ch == EOF;             // ist die while()-Schleife wegen '\n' oder EOF abgebrochen?
    	// wenn nicht, war es ein anderes Zeichen das nicht isspace() ist.
    }
    
    int main()
    {
    	int choice;
    	for (choice = 0; std::cout << "Input: " && !(std::cin >> std::noskipws >> choice) || !only_whitespace(std::cin) || (choice < 1 || 4 < choice);choice++)
    	{
    		std::cerr << "Input error!\n\n";    // eine Fehlermeldung ausgeben
    		std::cin.clear();                   // Fehlerflags loeschen, falls der Extraktionsversuch fehlgeschlagen ist
    
    		std::cin.ignore(                    // weitere Zeichen in cin ignorieren
    			std::numeric_limits< std::streamsize >::max(), // Anzahl zu ignorierender Zeichen, vorsichtshalber die groesztmoegliche Anzahl annehmen
    			'\n'                            // solange kein '\n' daherkommt
    			);
    	}
    	std::cout << choice << "\n\n";          // getroffene Auswahl ausgeben
    }
    


  • und? was bringt die Nachplapperei?



  • Die for-Schleife ist nicht richtig!!!



  • Wie wärs mit

    std::string str;
    std::getline(std::cin, str);
    int choice = boost::lexical_cast<int>(str); // Wirft Exception wenn str nicht nach int konvertiert werden kann
    

    ?



  • Es gibt an der for-Schleife nichts auszusetzen. Sie macht genau das, was Swordfish mit einer do-while-Schleife auch macht!



  • hustbaer schrieb:

    Wie wärs mit

    std::string str;
    std::getline(std::cin, str);
    int choice = boost::lexical_cast<int>(str); // Wirft Exception wenn str nicht nach int konvertiert werden kann
    

    ?

    Danke hustbaer, aber boost ist für mich jetzt nochmal eine neue Bibliothek. So lerne ich die Grundlagen nicht, wenn ich ständig auf eine Bibliothek ausweiche.
    Mit Boost Lexical_cast ist die Konvertierung von string to z.B. int sicherlich einfacher oder besser. Danke für deine Antwort.



  • MarkusMundM schrieb:

    #include <cctype>    // std::isspace()
    #include <limits>    // std::numeric_limits<>::max()
    #include <iomanip>   // std::noskipws()
    #include <iostream>
    
    bool only_whitespace(std::istream & is)       // true, wenn nur white-space Zeichen in is sind.
    {
    	std::istream::int_type ch = 0;
    
    	// solange das naechste Zeichen in is
    
    	while (ch != '\n' && ch != EOF              // kein Newline ist und auch das Streamende nicht erreicht ist
    		&& std::isspace(ch = is.peek())    // und ein Leerzeichen, Tab, ... ist (peek() nur ansehen, nicht extrahieren)
    		)
    	{
    		is.get();                               // extrahiere das Zeichen aus is (= werfe das angesehene Zeichen weg).
    	}
    
    	return ch == '\n' || ch == EOF;             // ist die while()-Schleife wegen '\n' oder EOF abgebrochen?
    	// wenn nicht, war es ein anderes Zeichen das nicht isspace() ist.
    }
    
    int main()
    {
    	int choice;
    	for (choice = 0; std::cout << "Input: " && !(std::cin >> std::noskipws >> choice) || !only_whitespace(std::cin) || (choice < 1 || 4 < choice);choice++)
    	{
    		std::cerr << "Input error!\n\n";    // eine Fehlermeldung ausgeben
    		std::cin.clear();                   // Fehlerflags loeschen, falls der Extraktionsversuch fehlgeschlagen ist
    
    		std::cin.ignore(                    // weitere Zeichen in cin ignorieren
    			std::numeric_limits< std::streamsize >::max(), // Anzahl zu ignorierender Zeichen, vorsichtshalber die groesztmoegliche Anzahl annehmen
    			'\n'                            // solange kein '\n' daherkommt
    			);
    	}
    	std::cout << choice << "\n\n";          // getroffene Auswahl ausgeben
    }
    

    @MarkusMundM, nein diese Schleife macht nicht dasselbe, was Swordfish bereits mit einer do-while Schleife gelöst hat.



  • OK.
    Aber du kannst ja mal reingucken wie Boost es macht 😉
    IIRC verwenden die nen (etwas modifizierten und auf etwas bessere Geschwindigkeit modifizierten) Stringstream.
    Da wird dann erstmal der Ausgangswert "reingeschiftet" (stream insertion, "<<" halt).
    Und dann wird versucht das "rauszushiften" (stream extraction, ">>") was man haben möchte.

    Und dann wird geprüft
    a) Ob der Stream danach noch "good" ist und
    b) Ob der Stream danach leer ist

    Wenn beides zutrifft war die Konvertierung erfolgreich.

    Finde ich weitaus eleganter als direkt in cin zu gucken ob auch wirklich ein Newline das nächste Zeichen ist.


Anmelden zum Antworten