Eingabeüberprüfung auf Ganzzahl bzw Gleitkommazahl



  • Die Aufgabe ist, vom Keyboard Ganzzahlen einzulesen & in nem Array zu speichern.

    Das Einlesen der Zahlen erledigt eine for-Schleife.

    for (index = 0; index < 11; index++)
    	{
    		printf ("Gib die %d. von 10 Ganzzahlen ein: ", index + 1);
    		scanf ("%d", &array1 [index]);
    	}
    

    Unmittelbar nach jeder Eingabe, soll überprüft werden, ob die eingegebene Zahl auch wirklich eine Ganzzahl ist, oder eine Gleitkommazahl bzw überhaupt etwas anderes (Text) eingegeben wurde.

    Welche Möglichkeiten habe ich zur Überprüfung?



  • Analog zur aktuellen Parallelfrage hier:

    int liesDouble(double *l)
    {
      char s[100],*e;
      errno=0;
      fgets( s,100,stdin );
      *l=strtod( s,&e );
      return (!*e||*e=='\n')&&errno!=ERANGE;
    }
    

    bzw. mit parametrisiertem String:

    int liesLong(long *l,const char *s)
    {
      char *e;
      errno=0;
      *l=strtol( s,&e,10 );
      return (!*e||*e=='\n')&&errno!=ERANGE;
    }
    int liesDouble(double *l,const char *s)
    {
      char *e;
      errno=0;
      *l=strtod( s,&e );
      return (!*e||*e=='\n')&&errno!=ERANGE;
    }
    ...
    char s[100];
    long l;
    double d;
    fgets( s,100,stdin );
    if( liesDouble(&d,s) )
      printf("Double: %f",d);
    else
    if( liesLong(&l,s) )
      printf("Long: %ld",l);
    else
      fputs("Fehler",stderr);
    

    wobei beim double-Lesen die aktuelle locale ('.' od. ',') berücksichtigt wird.



  • Die einfachste Herangehensweise dürfte das hier sein:

    if(scanf ("%d", &array1 [index]) == 1) {
      /* Geklappt */
    } else {
      /* Da steht was anderes im Stream */
    }
    

    Wobei dann natürlich das Verhalten von scanf bleibt, was beim Trennen von Ganz- und Fließkommazahlen problematisch sein könnte - "12.345" wird so als 12 geparst und ".345" bleibt im Stream zurück. Das ließe sich ziemlich direkt wie folgt umgehen:

    double tmp;
    if(scanf("%lf", &tmp) == 1 &&
       trunc(tmp) == tmp       && /* Prüfung, ob die eingelesene Zahl ein Integer ist */
       tmp <= INT_MAX          &&
       tmp >= INT_MIN)
    {
      array1[index] = (int) tmp;
    }
    


  • scanf macht keine Überlauf/Unterlaufprüfung und ist deshalb immer nur die halbe Wahrheit.



  • Scanf() ist auch mein erklärter Feind 😃
    Wenn jemand aus Versehen ein falsches Zeichen abschickt, hängt das Programm, da ungültige Zeichen bei Scanf() nicht aus dem Eingabepuffer gelöscht werden.



  • Eingelesenen String bis \n oder 0 (binär) durchsuchen, wenn
    was < '0' oder > '9' Eingabe falsch.
    das oder 0 weil man Eingaben auch mit ctl+d beenden kann. Es kommt nicht wirklich immer ein \n. Auch sollte man die definierte Länge des Strings nicht überschreiten.


Anmelden zum Antworten