Wiederholt einlesen mit scanf()?



  • Der Benutzer soll einen float-Wert eingeben. Wenn das nicht funktioniert, soll eine Fehlermeldung ausgegeben werden, und dann das ganze von vorn.

    float fradius;
    while (!scanf("%f", &fradius))
    {
      printf("\nFehler bei der Eingabe.\n");
    }
    

    Wenn der Benutzer eine Zahl eingibt, funktioniert das natürlich wunderbar. Wenn er aber zum Beispiel einen Buchstaben eingibt, wird immer wieder printf() aufgerufen, und das Programm denkt nicht dran, nochmal was einzulesen. Wieso und wie kann ich das umgehen?

    Ich verwende Microsoft Visual C++ 6 SP4.

    Nachtrag:
    Wenn ich hinter dem printf()

    while (getchar() != '\n');
    

    schreibe, geht es. Das verstehe ich ehrlich gesagt überhaupt nicht.

    [ Dieser Beitrag wurde am 15.10.2002 um 18:28 Uhr von OregonGhost editiert. ]



  • Wenn scanf fehlschlägt, z.B. weil es Pottwal gelesen hat, dann wird der interne 'Zeiger', der auf das aktuelle Zeichen zeigt _nicht_ vorgerückt. Also versucht scanf in der nächsten Runde gleich nochmal Pottwal zu lesen. Funktioniert wieder nicht. Mit dem getchar schiebst Du den Zeiger immer weiter, solang bis ein Zeilenumbruch gefunden wurde und versuchts dann nochmal. Das ist nicht gut, wenn ein EOF zurückgegeben wird, weil deine Schleife dann zur Endlosschleife wird.



  • Jetzt frage ich mich zum einen, wieso ein EOF zurückgeliefert werden sollte, und zum anderen, wie ich das sonst machen soll. Oder soll ich einfach nach EOF oder '\n' abfragen?



  • Wenn Du mit Windows arbeitest, kannst Du das Verhalten, wie's Daniel E. geschildert hat, so simulieren:

    lege mit "copy con test.txt" eine Datei mit folgendem Inhalt an:

    A<enter>
    B<Strg+Z>
    

    . Der Trick ist, dass nach dem B kein '\n' abgespeichert wird (die Datei ist hier zu Ende). Wenn Du jetzt Dein Programm so aufrufst

    meinprog < test.txt
    

    kommt's zum Absturz ... 🙂

    Um das ganze zu umgehen, liest Du nicht mit scanf(), sondern ganz normal mit fgets(), prüfst auf Fehler und zerlegst die Eingabe mit sscanf().



  • Du kannst Deine Schleife auch umbauen:

    int c;
    /* ... */
    while ((c = getchar()) != EOF && c != '\n') ;
    

    Obwohl mir diese Lösung nicht besonders gefällt.



  • wegen dem prob mit dem buchstaben und printf...
    keine ahnung ob das wirklich so richtig ist(bin newbie), geht aber:

    #include <stdio.h>
    
    int main(){
        float fradius;
        while (!scanf("%f", &fradius)){
                                       printf("\nFehler bei der Eingabe.\n");
                                       fflush(stdin);
                                       }
        return 0;
    }
    


  • Der Thread ist 4 Jahre alt, ich glaube inzwischen funktioniert das Programm... 😉



  • Dann bleibt eigentlich nur unserem Newbie mitzuteilen dass fflush(stdin) böse und die while-Schleife die bis EOF oder \n liest der "bevorzugte" Weg ist, das Problem zu lösen 😉



  • naja man ist ja hier um was zu lernen is doch egal wie alt der thread xD
    meine ja nur falls sich noch mehr newbies in diesem forum verschaun...
    hab oft dieses prob gehabt und weiß ja jetzt worans liegt 😃
    - vll haben andre nich das glueck und kommen jetzt drauf^


Anmelden zum Antworten