Frage zu readint



  • Ich arbeite gerade an meiner Semesteraufgabe.

    zu dem folgenden Programm habe ich eine Frage:

    und zwar habe ich bei der fehlerbehandlung ein problem. es soll zahlen von 1 bis 3 erkennen. aber wenn ich jetzt 3 7 eingebe erkennt er es trotzdem als 3 und nicht als fehler. ich finde den fehler einfach nicht kann mir jemand helfen??
    /*************************************************************************
    *
    * Name: readint
    *
    * Zweck: Einlesen einer int-Zahl von der Tastatur mit
    * Fehlerbehandlung.
    * Das Programm stellt sicher, dass ein Wert in einem
    * vorgegebenen Bereich eingelesen wird.
    *
    * Prototyp: int readint(const char msg[], int lower, int upper);
    *
    * Parameter: msg: (E) Aufforderungsmeldung.
    *
    * lower: (E) Untere Grenze des zulaessigen Bereichs.
    *
    * upper: (E) Obere Grenze des zulaessigen Bereichs.
    *
    * Funktionswert: Eingelesener Wert.
    *
    *************************************************************************/

    int readint(const char msg[], int lower, int upper) 
    { 
       int zahl, n; 
    
       do 
       { 
          printf("%s", msg); 
          n = scanf("%d", &zahl); 
          while (getchar() != '\n' && getchar() != ' ') 
             ; 
          if (n != 1) 
             printf("\n*** Eingabefehler\n\n"); 
          else if (zahl < lower) 
          { 
             printf("\n*** Der Wert muss groesser oder gleich %d sein!\n\n", 
                    lower); 
             n = 0; 
          } 
          else if (zahl > upper) 
          { 
             printf("\n*** Der Wert muss kleiner oder gleich %d sein!\n\n", 
                    upper); 
             n = 0; 
          } 
       } while (n != 1); 
       return zahl; 
    }
    


  • Mach´s doch so:

    int readint(const char msg[], int lower, int upper) 
    { 
       	int zahl, n; 
    
    	printf("%s\n", msg);
    	scanf("%d", &zahl);
    	while(getchar()!='\n');
    
    	while ( zahl < lower || zahl > upper )
    	{
    		printf("Zahl muss im Intervall [%d,%d] liegen!\n", upper, lower);
    		scanf("%d", &zahl);
    		while(getchar()!='\n');		
    	}
    
    return zahl;
    }
    


  • Ich habe es mal ausprobiert. ich weiß nicht ob ich etwas falsch gemacht habe aber der fehler ist immernoch da. Mit dem programm wähle ich nachher im menü die einzelnen Punkte aus. Und wenn ich bei meiner und bei der deiner version den richtigen wert also 1, 2 oder 3 eingebe geht es ja aber gebe ich z.b. 3 7 oder 2 5 ein. also einen richtigen wert leerzeichen und dann einen anderen wert ein. greift er trotzdem auf den menüpunkt aber das soll er ja nict er soll so zu sagen das leerzeichen erkennen und dann sagen das es falsch ist was man da gemacht hat. geht es überhaupt das er das leerzeichen erkennt und dann sagt das es falsch ist? nicht das ich mir hier seit tage den kopf zerbreche und das nachher garnicht geht.



  • Mit scanf kommst du da wahrscheinlich nicht weiter denn scanf stoppt bei einem whitespace. Dir wird nichts anderes übrigbleiben als erst einmal die ganze zeile z.b mit fgets() einzulesen und dann zu validieren.
    Kurt



  • da habe ich dann wieder ein problem weil wenn ich mich recht erinnere hatten wir fgets in den vorlesungen noch nicht.

    ich werde mal in meinen unterlagen schauen und berichten aber danke für den vorschlag



  • Hallo Rotasch.
    Studierts du zufällig an der FH-Kiel ?

    a aber gebe ich z.b. 3 7 oder 2 5 ein. also einen richtigen wert leerzeichen und dann einen anderen wert ein. greift er trotzdem auf den menüpunkt aber das soll er ja nict

    Zuk hat das schon geschriben aber ich erkläre es noch mal.
    Wenn du die Zahl als int einliest sprich mit %d, dann ist es leider nicht möglich diesen Fehler abzufangen (so weit ich weiss).
    Die Parameterliste von scanf einthält ja nur ein Formatierungselement.
    Das heisst wenn die erste Zahl erfolgreich eingelesen worden ist, analysiert scanf nicht weiter was sich im stdin befindet, liefert 1 zurück, und alles scheint in Ordnung zu sein, naja bis auf den Schönheitsfehler ist auch alles in Ordnung.

    Die Einzige Lösung wäre die Zahl als Zeichenkette einzulesen (mit %s als Formatirungselement) und aus der Zeichenkette dann die Zahl herauszufiltern oder eventuelle Fehleigaben.
    Das ist aber aufwendig und erfordet, dass man zu Funktionen greift die:
    "hatten wir [..] in den vorlesungen noch nicht"



  • fgets, strtok, strtol/strtof
    ein beispiel zu fgets+strtok+strtol hab ich in einem anderen thread gepostet



  • Marcin schrieb:

    Die Einzige Lösung wäre die Zahl als Zeichenkette einzulesen (mit %s als Formatirungselement) und aus der Zeichenkette dann die Zahl herauszufiltern oder eventuelle Fehleigaben.

    %s liest aber auch nur bis zum nächsten Whitespace, bringt also gegenüber %d keine große Verbesserung - wenn du bis zum nächsten Zeilenwechsel lesen willst, bleibt man: fgets oder scanf("[%[^\n]",s); (liest alle Zeichen aus der gegebenen Menge).



  • %s liest aber auch nur bis zum nächsten Whitespace

    Ja stimmt das ist mir gestern entfallen.
    Man müsste sich also doch fgets bedienen.
    Das ist aber eigentlich egal. fgets und alles andere was in der Vorlesung noch nicht gab, darf nicht im Quellcode vorkommen.



  • Marcin schrieb:

    Das ist aber eigentlich egal. fgets und alles andere was in der Vorlesung noch nicht gab, darf nicht im Quellcode vorkommen.

    Kamen denn die Format-Kennungen von man: scanf schon in der Vorlesung dran? Die Kennung %[ wäre möglicherweise das richtige für dich.

    Plan B wäre es, nach dem scanf zu überprüfen, ob dort noch etwas im Puffer liegt.



  • Plan B wäre es, nach dem scanf zu überprüfen

    Nach diversen Versuchen habe ich festgestellt dass die beste Lösung ist.


Anmelden zum Antworten