Eingabe überprüfen (Integer)



  • Hallo zusammen

    Ich habe folgendes Problem.Ich habe ein Programm, bei welchem wahlweise Kanal 1 oder Kanal 2 oder aber auch Kanal 3 gewählt werden kann. Ich habe dies mit Eingabe von Zahlen gemacht, und zwar folgendermassen:
    1=Kanal 1
    2=Kanal 2
    3=Kanal 1+2

    Die Eingabe wird dann so lange wiederholt, bis eine Zahl zwischen 1 und 3 eingegeben wird. Wird nun jedoch fälschlicherweise ein Buchstabe oder ein Wort eingetippt, so bekomm ich eine Endlos-Schlaufe. Ich habe den erneuten Aufrug mit einer do-while Schleife gemacht. Ist es möglich bei der while-Anweisung so etwas wie: while (gKanal!= "von Typ Integer") anzufügen?
    Oder gibt es eine andere Lösung?

    Der Code sieht wie folgt aus:

    // Test.cpp: Hauptprojektdatei.
    
    #include "stdafx.h"
    #include <iostream>
    #include <conio.h>
    using namespace std;
    
    void main()
    {
       int gKanal;
    
    	do	//In dieser Do-While-Schelife wird geprüft, ob die Eingabe gültig ist. Wenn nicht wird der Text wieder ausgegeben!
    	{
    		cout << "Welche Kanaele sollen gemessen werden?" << endl;
    		cout << "Wahelen Sie 1 fuer Kanal 1" << endl;
    		cout << "Wahelen Sie 2 fuer Kanal 2" << endl;
    		cout << "Wahelen Sie 3 fuer Kanal 1+2" << endl;
    		cout << "Wahelen Sie nun den entsprechenden Kanal : " << endl;
    
    		cin >> gKanal;
    	}
    	while (gKanal >3 || gKanal==0);
    
    	char ch=getch ();
    }
    


  • Du kannst in der Schleife überprüfen, ob die Zahl 1,2 oder 3 eingegeben worden ist.

    while( Eingabe != 1 && Eingabe != 2 && Eingabe != 3 )
    // oder
    
    while ( Eingabe < 1 && Eingabe > 3 )
    

    wobei mir ersteres besser gefällt



  • Müsste ich da "Eingabe" durch gKanal ersetzten? Hab es eben probiert, und funktioniert irgendwie nicht. Hab immer noch eine Endlos-Schleife.



  • OK jetz verstehe ich dein Problem. Wenn du eine falsche Eingabe tätigst, wird der Stream in einen Fehlerzustand gesetzt. Die Fehleingabe bleibt im Stream erhalten und erzeugt bei dir eine Endlosschleife. Du kannst den Fehler mit std::cin.clear() rücksetzten und mit http://www.cplusplus.com/reference/istream/istream/ignore/ überspringen.



  • Dies wird aber nicht in die while-Anweisung geschrieben oder?



  • char c = _getch();
    if(c == '1' ¦¦ c == '2' ¦¦ c == 3)
        std::cout << "Korrekte Eingabe";
    


  • JIPOOP schrieb:

    char c = _getch();
    if(c == '1' ¦¦ c == '2' ¦¦ c == 3)
        std::cout << "Korrekte Eingabe";
    

    falsch



  • Wie muss dann dieses std::cin.clear()eingesetzt werden? Einfach in der Schalufe funktioniert es nicht.
    Die Lösung mit nur 1,2 oder 3 zulassen find ich nicht wirklich gut, weill wenn ich eine Eingabe von 0-100 hätte könnte ich ja auch nicht jede Za^hl einzlen "ausschliessen".

    Seh im Moment wirklich nicht durch, hoffe es kann mir jemand helfen.

    Vielen Dank schon im voraus.



  • Du machst folgendes:

    int input = -1; // Oder irgendwas anders, "ungültiges"
    
    while (!cin >> input) // Solange das Lesen von ints nicht klappt
    {
        cerr << "Fehlerhafte Eingabe!" << endl;
        cin.clear();
    }
    // Input beschränkenm auf [min, max)
    if (input < min)
        input = min;
    else if (input >= max)
        input = max;
    //input verwenden
    


  • So, oder versteh ich was komplett falsch?

    // Test.cpp: Hauptprojektdatei.
    
    #include "stdafx.h"
    #include <iostream>
    #include <conio.h>
    #include <limits>
    
    using namespace std;
    
    void main()
    {
       int input=-1;
       int min=0;
       int max=3;
    
    	do	//In dieser Do-While-Schelife wird geprüft, ob die Eingabe gültig ist. Wenn nicht wird der Text wieder ausgegeben!
    	{
    
    		cout << "Welche Kanaele sollen gemessen werden?" << endl;
    		cout << "Wahelen Sie 1 fuer Kanal 1" << endl;
    		cout << "Wahelen Sie 2 fuer Kanal 2" << endl;
    		cout << "Wahelen Sie 3 fuer Kanal 1+2" << endl;
    		cout << "Wahelen Sie nun den entsprechenden Kanal : " << endl;
    
    		cin >> input;
    
    	}
    
    	while (!cin >> input); // Solange das Lesen von ints nicht klappt 
    { 
        cerr << "Fehlerhafte Eingabe!" << endl; 
        cin.clear(); 
    } 
    
    	if (input < min) 
        input = min; 
    	else if (input >= max) 
        input = max; 
    
    	char ch=getch ();
    }
    


  • evo-style schrieb:

    So, oder versteh ich was komplett falsch?

    Was ist jetzt genau das Problem an deinem Quellcode?

    An alle anderen: Ich frage mich gerade... Wie stelle ich sicher, dass der Benutzer wirklich, wirklich nur eine Ganzzahl eingeben kann? while (!cin >> input)( klappt ja immer, wenn am Anfang eine Zahl steht... Mein schneller Ansatz wäre das hier? Aber das geht bestimmt noch besser?

    #include <iterator>
    #include <limits>
    #include <string>
    #include <sstream>
    #include <cctype>
    #include <iostream>
    using namespace std;
    
    int is_integer(const string& str)
    {
    	if( str.length()==0 )
    		return numeric_limits<int>::min();
    
    	const unsigned minus = str[0]=='-' ? 1 : 0;
    
    	for(string::const_iterator it=str.begin()+minus; it!=str.end(); ++it)
    	{
    		if( !isdigit(*it) )
    			return numeric_limits<int>::min();
    	}
    
    	istringstream iss(str);
    	int integer;
    	iss>>integer;
    	return integer;
    }
    
    int main()
    {
    	int n;
    	for(n=numeric_limits<int>::min(); n==numeric_limits<int>::min(); )
    	{
    		string str;
    		getline(cin,str);
    		n = is_integer(str);
    	}
    
    	cout << "Zahl: " << n;
    }
    

  • Mod

    out schrieb:

    An alle anderen: Ich frage mich gerade... Wie stelle ich sicher, dass der Benutzer wirklich, wirklich nur eine Ganzzahl eingeben kann? while (!cin >> input)( klappt ja immer, wenn am Anfang eine Zahl steht... Mein schneller Ansatz wäre das hier? Aber das geht bestimmt noch besser?

    Mein Tipp: Ist das wirklich wichtig? Das ist doch nicht die typische Anwendung der Streamoperatoren oder wie ein typisches Konsolenprogramm genutzt wird. Du baust mit viel Aufwand eine (Text-)GUI nach. Wenn man so etwas möchte, dann nehme man doch gleich ein fertiges GUI-Framework.
    Ich halte das jedenfalls immer so, dass davon ausgegangen wird, dass der Benutzer weiß, was er tut. Wenn eine Eingabe fehlerhaft war, dann war sie eben fehlerhaft. Das Programm arbeitet dann (je nach Wichtigkeit der Eingabe) so weiter als ob die Eingabe das Streamende war oder es bricht ab.

    P.S.: Natürlich kann man das mit viel Aufwand alles hinfummeln, aber das mag ich gerade nicht vormachen.



  • evo-style schrieb:

    So, oder versteh ich was komplett falsch?

    // Test.cpp: Hauptprojektdatei.
    
    #include "stdafx.h"
    #include <iostream>
    #include <conio.h>
    #include <limits>
    
    using namespace std;
    
     
    
    void main()
    {
       int input=-1;
       int min=0;
       int max=3;
    
       
    
    	do	//In dieser Do-While-Schelife wird geprüft, ob die Eingabe gültig ist. Wenn nicht wird der Text wieder ausgegeben!
    	{
    		
    		cout << "Welche Kanaele sollen gemessen werden?" << endl;
    		cout << "Wahelen Sie 1 fuer Kanal 1" << endl;
    		cout << "Wahelen Sie 2 fuer Kanal 2" << endl;
    		cout << "Wahelen Sie 3 fuer Kanal 1+2" << endl;
    		cout << "Wahelen Sie nun den entsprechenden Kanal : " << endl;
    		
    		cin >> input;
    	
    		
    	}
    
    	while (!cin >> input); // Solange das Lesen von ints nicht klappt 
    { 
        cerr << "Fehlerhafte Eingabe!" << endl; 
        cin.clear(); 
    } 
    
    	if (input < min) 
        input = min; 
    	else if (input >= max) 
        input = max; 
    
    	char ch=getch ();
    }
    

    Lösche das cin.clear() und das cerr und füge am Anfang der do-while-Schleife cin.clear() ein.

    @out:
    Bei cin >> integer wird doch abgebrochen, sobald das erste nicht Zahl-zeichen ist (bei richtiger Benutzung bei Enter, bei falscher bei irgendeinem anderen char). Also wo ist dein Problem?



  • Nathan schrieb:

    @out:
    Bei cin >> integer wird doch abgebrochen, sobald das erste nicht Zahl-zeichen ist (bei richtiger Benutzung bei Enter, bei falscher bei irgendeinem anderen char). Also wo ist dein Problem?

    int main()
    {
    	int input;
    	while (!(cin >> input)) // Eingabe: 5.5
    	{
    		cerr << "Fehlerhafte Eingabe!" << endl;
    		cin.clear();
    	}
    
    	double d;
    	cin >> d; // 0.5
    }
    

    Wie handelst du das hier?



  • Ich lösche vorher den Buffer mit cin.ignore()?



  • Nathan schrieb:

    Ich lösche vorher den Buffer mit cin.ignore()?

    Ja schon. Ich wollte damit nur sagen, dass eine eigentlich fehlerhafte Eingabe als gültig angesehen wird.


Anmelden zum Antworten