Überprüfung



  • Ich meine es soll ganz zahlen rein, und wenn man einen string oder double eingibt soll es eine Fehlermeldung ausgeben und das Programm soll sich nicht selber beenden.
    So etwas:

    int c,d;
    cin >> c >> d;
    if (int != c || int != d) error("Das ist kein Integer");
    

    Ich weiß das der Code falsch ist nur so kann ich sagen was ich meine.



  • #include <iostream>
    #include <string>
    #include <stdlib.h>
    
    int main(void)
    {
    	char TempBuffer = '\0';
    	std::string Buffer;
    
    	do
    	{
    		if(TempBuffer != '\0')
    			Buffer.push_back(TempBuffer);
    
    		TempBuffer = getc(stdin);
    
    	} while(TempBuffer > 48 && TempBuffer < 57);
    }
    


  • while(TempBuffer > 48 && TempBuffer < 57);
    

    kannst du das erklären ? 🙂



  • Jetzt ist mir eins klar als ich das Buch (Einführung in die Programmierung mit C++) durchblättere. Man kann das mit dem Fehler abfangen nur vor der schleife machen als nicht in der schleife.


  • Mod

    Ungetestet ungefähr so:

    while(!(cin>>i))
    {
     cin.clear();
     // Fehlermeldung anzeigen;
     cin.ignore(/*eines oder alle Zeichen*/);
    }
    


  • Ich habe es so geschrieben:

    int c,d;
    while (!(cin>>c || cin>>d)){
    	 cin.clear(); 
                 error ("Please put an integer \n");
    	 cin.ignore('!');
    }
    

    Da es zwei Integer überprüfen soll. Doch irgendwie will das nicht. Wenn ich ein Double eingebe beendet sich das Programm.



  • Ich mach das eigentlich immer so, in diesem Fall zb. bei einem simplen Taschenrechner:

    #include <conio.h>
    //...
    int a, b;
    char token;
    cout << "Gebe einen Term ein: (zb 2+6) ";
    if(!(cin >> a)) {
        cerr << "Fehler bei der Eingabe!\n";
        _getch();
        return -1;
    }
    cin >> token;
    if(!(cin >> b)) {
        cerr << "Fehler bei der Eingabe!\n";
        _getch();
        return -1;
    }
    cout << a << token << b;
    //usw.
    

    Nur beendet sich da das Prog, die Variante mit cin.ignore() hat bei mir nie geklappt. Was ist daran denn auch so schlimm? Mich stört das eigentlich nicht.
    Würde mich aber auch interessieren ob hier endlich mal eine funktionierende Lösung gepostet wird. 🙂



  • winux schrieb:

    Ich habe es so geschrieben:

    int c,d;
    while (!(cin>>c || cin>>d)){
    	 cin.clear(); 
                 error ("Please put an integer \n");
    	 cin.ignore('!');
    }
    

    Da es zwei Integer überprüfen soll. Doch irgendwie will das nicht. Wenn ich ein Double eingebe beendet sich das Programm.

    Kleines Fallbeispiel - du gibst folgendes ein: 3 4.23
    Resultat: alles ok - c hat den Wert 3 und d hat den Wert 4

    Anderes Beispiel - Eingabe: 3 .3f
    Resultat: c hat den Wert 3 aber d konnte nicht eingelesen werden. Da du aber geschrieben hast while (!(cin>>c || cin>>d)) wird die while-Schleife abgebrochen. Warum? cin>>c wird als wahr ausgewertet. Bei einem logischen Oder reicht es wenn einer der Operanden wahr ist um den Ausdruck als wahr auszuwerten. Demzufolge ist (cin>>c || cin>>d) nun also wahr. Du negierst das ganze dann noch --> es wird false. Somit wird die while-Schleife nicht durchlaufen.

    Was du möchtest ist etwas in der Art (wie SeppJ ja bereits zeigte):

    int a,b;
    while (!(std::cin>>a>>b)) {
    	std::cout<<"\nFehler - bitte neu eingeben\n";
    	std::cin.clear();
    	std::cin.ignore(std::cin.rdbuf()->in_avail());
    }
    

    wobei ich meine mich erinnern zu können, dass SeppJ mal erwähnte, man soll sich nicht auf das letzte statement verlassen. Müsste ich mir nochmal genauer ansehen warum und wie etc.



  • Wenn ich bei mir allerdings diese Variante laufen lasse, also das hier:

    int a,b;
    while (!(std::cin>>a>>b)) {
        std::cout<<"\nFehler - bitte neu eingeben\n";
        std::cin.clear();
        std::cin.ignore(std::cin.rdbuf()->in_avail());
    }
    

    Und ich was falsches eingebe (zb einen Buchstaben), dann erscheint eine Endlosschleife mit "\nFehler - bitte neu eingeben\n"..



  • Siehe http://www.c-plusplus.net/forum/35473. Dort wird auch eine Lösung präsentiert.



  • Ahh so hats geklappt, aber eine Frage hab ich noch. Ich hab mir jetzt eben schnell was hingeschmiert:

    #include <limits>
        //..code
        if(!cin) {
            cerr << "Fehler bei der Eingabe! Nochmal eingeben!\n";
            cin.clear();
            cin.ignore(numeric_limits<int>::max(), '\n');
            continue;
        }
    

    Aber was machen diese beiden Zeilen hier?

    cin.clear();
    cin.ignore(numeric_limits<int>::max(), '\n');
    


  • jetzt wäre doch der perfekte Zeitpunkt, sich mit der Doku zu beschäftigen, oder?

    clear:
    http://www.cplusplus.com/reference/iostream/ios/clear/

    ignore:
    http://www.cplusplus.com/reference/iostream/istream/ignore/



  • Das ist der Code mit dem ich Arbeite.

    #include "stdafx.h"
    #include "std_lib_facilities.h"
    
    void rand_in_range(int a,int b){
         cout << randint(a - b) + b << endl;
    }
    
    void calc(){
    	cout << "Please enter 2 integer to generate a number\n";
    	cout << "To exit enter any char\n";
        int c,d;
    	while (cin >> c >> d){
            if (!(cin)){
    		cout << "Error in the Input! Re-enter!\n"; 
            cin.clear(); 
            cin.ignore(numeric_limits<int>::max(), '\n'); 
            continue;} 
    		else{
    		rand_in_range(c,d);}
            }
    }
    
    int main()
    try{
    	calc();
    
    	keep_window_open();
        return 0;
    }
    catch (runtime_error e) {	
    	cout << e.what() << '\n';
    	keep_window_open("~");	
    }
    catch (...) {	
    	cout << "exiting\n";
    	keep_window_open("~");	
    }
    

    Doch wenn ich einen Buchstaben oder Double eingebe beendet sich das Programm.



  • winux schrieb:

    Das ist der Code mit dem ich Arbeite.

    //..snip..
        int c,d;
    	while (cin >> c >> d){        // <-------- 1
            if (!(cin)){              // <-------- 2
    		cout << "Error in the Input! Re-enter!\n"; 
            cin.clear(); 
            cin.ignore(numeric_limits<int>::max(), '\n'); 
            continue;} 
    		else
    		rand_in_range(c,d);
            }
    //..snap..
    

    Doch wenn ich einen Buchstaben oder Double eingebe beendet sich das Programm.

    zu 1.) Nur wenn die Bedingung wahr ist - wird die Schleife durchlaufen, und zwar solange sie wahr ist. Der Operator >> mit einem stream als linksseitigem Operanden liefert eine Referenz dieses Streams zurück. Der Stream verwaltet intern Zustandsflags die angeben, in welchem Zustand sich der stream befindet. Wenn alles ok ist ist dieser Wert 0 was dem goodbit entspricht. Soll ein int eingelesen werden aber du lieferst beispielsweise einen Buchstaben, so wird das failbit gesetzt.
    Testest du nun den stream in einer Bedingung auf einen Wahrheitswert wird überprüft, welche flags gesetzt sind. Wenn der stream in Ordnung ist (goodbit) wird true geliefert, anderenfalls false.

    Lange Rede kurzer Sinn: Wenn du while (cin>>c>>d) schreibst und beispielsweise einen Buchstaben eingibst, wird das failbit gesetzt, vom operator>> per return-by-reference der stream zurückgegeben, dieser dann auf Wahrheitswert getestet und dieser liefert dann aufgrund des gesetzten failbits den Wert false.
    Resultat: die while-Schleife wird nicht durchlaufen und somit auch nicht deine zweite Zeile (2) if(!(cin)).



  • OK jetzt hab ich wieder etwas gelernt. Also muss man das schon vor der schleife abfangen. Danke an alle für die Hilfe.


Anmelden zum Antworten