Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (ANSI-Standard) » Eingabeabsicherung

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 <
000
05.12.2004, 15:33 Uhr
enrico



Hallo habe folgendes Problem: Hab mir ne Klasse Datum geschrieben mit ner Bool-Fkt. setDatum, die prüft ob es ein gültiges Datum ist. Funktioniert auch alles super, wenn ich ein ungültiges Datum eingebe liest er es nicht ein sondern gibt ne Fehlermeldung aus. Das Problem was ich habe ist aber, dass er dann an der Stelle stehen bleiben soll und der Nutzer die Möglichkeit bekommt ein neues Datum einzugeben, bei mir geht er dann nämlich einfach den Rest der Funktion durch und man hat keine Möglichkeit mehr irgendetwas einzugeben und er nimmt Werte uas den Konstruktoren.

Hier mal nacheinander die Quelltextabschnitte die aufgerufen werden.

Zuerst die Eingabe:

C++:
cout<<"Wann soll die Aktivitaet beginnen?"<<endl;
cout<<"Eingabe im Format Tag.Monat.Jahr: ";
if (!(cin>>tg>>c>>mn>>c>>j))        // Wenn Startdatum der Aktivitaet ungültig
     cerr<<"Ungülige Eingabe!\n"<<endl;    // Fehlermeldung
else a1->setvon(tg,mn,j);            // Sonst einlesen



Dann die Funktion setvon:



C++:
// Startdatum der Aktivitaet festlegen
void Aktivitaet::setvon(short tg, short mn, short j){
// Übergabe des Start- Tags/-Monats/-Jahrs

if (!von.setDatum(tg, mn, j)){    // Wenn Datum ungültig dann
   cerr<<"Ungülige Eingabe!"<<endl;    // Fehlermeldung, sonst wird Datum eingelesen
    }
}



Und so sieht die Funktion setDatum in der Klasse Datum aus:


C++:
bool Datum::setDatum(short tg, short mn, short j){
    if (tg < 1 || tg > 31) return false;        // ungültiger Tag
    if (mn < 1 || mn > 12) return false;        // ungültiger Monat

    switch(mn){            // "Case Monat of"
    case 2: if(isLeapYear(j)){        // Wenn Schaltjahr und Februar ist
        if (tg > 29)        // Darf Tag nicht größert als 29 sein
            return false;                // sonst gib falsch zurück
            }        
        else if (tg > 28)          // sonst darf Tag n icht größer 28 sein
            return false;        // sonst gib falsch zurück
        break;            // verlasse die Anweisung
    case 4:                // April,
    case 6:                         // Juni
    case 9:                         // September
    case 11:                // November
        if(tg > 30) return false;        // Tag darf nicht größer 30 sein
    }
    tag = tg;                // Tag,
    monat = mn;            // Monat,
    jahr = j;                // Jahr intialisieren
    return true;                             // wahr zurück
}

 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
05.12.2004, 15:41 Uhr
typecast
aka loddab
(Operator)


Frag einfach so lange nach einem Datum, bis ein gueltiges eingeben wurde:


C++:
while (!von.setDatum(tg, mn, j) {
  std::cerr << "Ungueltige Eingabe" << std::endl;
  std::cout << "Bitte neue Werte eingeben: ";
  std::cin >> tg >> mn >> j;
}



--
All parts should go together without forcing. ... By all means, do not use a hammer. (IBM maintenance manual, 1925)
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
05.12.2004, 15:48 Uhr
enrico



Ja so ähnlich hat ich es schon probiert, aber ich versuchs mal mit deiner Variante! Schönen Dank erstmal, aber eine Frage hab ich noch, was hat das std::...? Ist das ne Funktion der std Klasse (using namespace std??) oder was hat es damit auf sich?
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
05.12.2004, 16:47 Uhr
typecast
aka loddab
(Operator)


Die Klassen, Variablen und Funktionen der C++ Standardbibliothek (also gerade cin, cout, ...) befinden sich im Namensraum std.

Wenn man eine Varible aus dem Namensraum ansprechen willst, dann musst du std::variablenname (also hier std::cout) schreiben.

Um das zu umgehen kannst du auch using namespace std; schreiben. Der Kompiler liest dann cout << .... und ersetzt dass dann durch std::cout << ...
--
All parts should go together without forcing. ... By all means, do not use a hammer. (IBM maintenance manual, 1925)
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
05.12.2004, 23:33 Uhr
enrico



Hab nochmal ne Frage zum selben Thema:

ich hab es jetzt im Prinzip wie oben erwähnt geändert, der Quelltext sieht jetzt so aus:

C++:
cout<<"Wann soll die Aktivitaet beginnen?"<<endl;
m = false;
do{
             cout<<"Eingabe im Format Tag.Monat.Jahr: ";
             if(!(cin>>tg>>c>>mn>>c>>j)){
        cerr<<"Ungültige Eingabe!";
        m = false;
    }
    else{
        m = true;
        a1->setvon(tg,mn,j);                        }
}while(m = false);



und die setvon-Methode so:

C++:
void Aktivitaet::setvon(short tg, short mn, short j){    
    char c;
    while(!von.setDatum(tg, mn, j)){                            cerr<<"Ungülige Eingabe!"<<endl;                //
        cout<<"Bitte neues Datum eingeben: ";
        cin>>tg>>c>>mn>>c>>j;
    }
}



und die scheint auch zu funktionieren, wenn man wenigstens nen short-Wert als tg, mn und j übergibt. Aber wenn da schon was falsch übergeben wird geht auch die nicht. Deshalb die Absicherung oben, allerdings ist da das Problem, wenn man das im falschen Format(also ohne Punkte eingibt, gibts ne Endlosschleife und weiß nicht woran es liegt.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
06.12.2004, 01:26 Uhr
typecast
aka loddab
(Operator)


So jetzt erst mal zu deinem Problem mit der Endlosschleife:

Wenn du zum Beispiel:


Code:
121212


eingibst, dann wird das Programm (wie du schon festgestellt hast) in eine Endlosschleife gehen.
Der Grund dafuer ist der, dass cin sich in einem Fehlerzustand befindet und niemals etwas anderes liest.
D.h., dass m in deinem Code nie auf true gesetzt wird.
Um das zu beheben musst du als allererstes die Errorflags loeschen:


C++:
cin.clear();



Das wird aber nicht reichen, dass sich eventuell noch Zeichen im Stream befinden koennen, die muessen erst weggeschmissen werden:


C++:
cin.ignore(INT_MAX, '\n')



Das ignoriert die naechsten INT_MAX Zeichen (frag mich jetzt nicht wieviele das sind. So ein int ist ganz schoen gross), bis es auf ein '\n' trifft (also das newline Zeichen).
Da am Ende der Eingabe immer Enter gedrueckt wird, werden so alle Zeichen, die du eingeben hast weggeworfen.

Ich wuerde den Code noch ein wenig anders schreiben:


C++:
        do {
                cout<<"Wann soll die Aktivitaet beginnen?"<<endl;
                cout<<"Eingabe im Format Tag.Monat.Jahr: ";
                if(!(cin>>tg>>c>>mn>>c>>j)){
                        cerr<<"Ungueltige Eingabe!" << endl;
                        cin.clear();
                        cin.ignore(INT_MAX, '\n');
                }
        } while (von.setDatum(tg, mn, j);



Wenn du direkten Zugriff auf "von" hast, Ansonsten laesst du halt a1->setvon() einen Wert zurueckgeben, ob es geklappt hat oder nicht.
setvon wuerde dann aber so aussehen:


C++:
Aktiviataet::setvon(...) {
von.setDatum(...);
}



Aber ich kenne ja den gesammten Code nicht. Deshalb musst du entscheiden, wie du es machst.
--
All parts should go together without forcing. ... By all means, do not use a hammer. (IBM maintenance manual, 1925)
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
006
06.12.2004, 01:54 Uhr
enrico



Ja das funktioniert einwandfrei! Hast mir echt doll geholfen, da wäre ich wohl von alleine niemals drauf gekommen.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 <     [ C / C++ (ANSI-Standard) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: