scanf - eingegebenes Format überprüfen



  • Hallo zusammen!

    Ich hoffe, dass ihr mir bei einem kleinen Problem helfen könnt 🙂

    Und zwar habe ich heute einen sehr einfachen Einpresstiefen-Rechner für Autofelgen programmiert - soweit funktioniert das Programm auch schon, jedoch gibts da noch ein paar Kleinigkeiten, die ich gerne optimieren möchte.

    Das Programm ist vom Prinzip her sehr simpel: Es werden am Anfang 6 Zahlen eingelesen. Mit diesen 6 Zahlen, werden anschließend 3 Werte berechnet und entsprechend ausgegeben.

    Das Einlesen der 6 Zahlen wird mittels scanf durchgeführt.
    Nun möchte ich gerne die Überprüfung des eingegebenen Formates ergänzen.

    Bei den Zahlen handelt es sich um den Datentyp float.

    Die Überprüfung mit Hilfe des Rückgabewertes habe ich schon erfolgreich getestet, jedoch werden hiermit auch sinnlose Werte, wie z.B. "8+" oder "17g" akzeptiert.

    Nun möchte ich also, dass jede einzelne Ziffer überprüft wird, ob ihr Wert im Bereich 0-9 liegt. Weiters soll 1 Komma pro Zahl erlaubt sein.

    Wird der Wert im richtigen Format eingegeben, soll in der Programm-Routine fortgefahren werden, wird das falsche Format eingegeben, soll die Abfrage einfach ein weiteres Mal durchgeführt werden - solange, bis das korrekte Format folgt.

    Danke für eure Unterstützung!

    MfG hofmanius

    #include <conio.h>
    #include <stdio.h>
    
    int main (void)
    {
    
    float zahl1, zahl2, zahl3, zahl4, zahl5, zahl6;
    
    printf("1. Zahl: ");
    scanf("%f",&zahl1);
    
    printf("2. Zahl: ");
    scanf("%f",&zahl2);
    
    ...   // Einlesen der restlichen Zahlen
    
    // Berechnung der Werte
    
    // Ausgabe der Werte
    
    return 0;
    
    }
    


  • Schau dir einfach den Rückgabewert von man: scanf(3) an

    if(scanf("%f",&zahl2) != 1) {
      // Fehlerhafte eingabe
    }
    


  • rüdiger schrieb:

    Schau dir einfach den Rückgabewert von man: scanf(3) an

    Das mit dem Rückgabewert habe ich vorhin schon probiert - es hat auch im Großen und Ganzen funktioniert.

    Wenn ich z.B. einen Buchstaben eingeben habe, wurde ich zu einer erneuten Eingabe aufgefordert, bis das Format passte.

    Wenn ich aber bei der Lösung mit dem Rückgabewert z.B. eine Zahl UND einen Buchstaben eingeben, wird dieser Wert akzeptiert und mit einem völlig falschen Wert im Programm weitergerechnet.

    Deshalb möchte ich gerne jede einzelne Ziffer auf ihren Wert (0-9) überprüfen und zusätzlich 1 Komma pro Wert erlauben.



  • Dann liest Du ganz einfach einen eingegebenen String in ein Char Array, das Du im Anschluss in einer Schleife durchläufst und dort prüfst, ob jeder einzelne Char nur die von Dir gewünschten Wertebereiche verwendet und führst einen Zähler für Komma mit entsprechender Abfrage.
    Denke dabei aber an die passende Größe des Char-Arrays und eine Begrenzung der Stringlänge im scanf.



  • hofmanius schrieb:

    Wenn ich aber bei der Lösung mit dem Rückgabewert z.B. eine Zahl UND einen Buchstaben eingeben, wird dieser Wert akzeptiert und mit einem völlig falschen Wert im Programm weitergerechnet.

    1x wird eben als 1 gelesen und beim nächsten scanf versucht er ein x zu lesen und das schlägt fehl.

    hofmanius schrieb:

    Deshalb möchte ich gerne jede einzelne Ziffer auf ihren Wert (0-9) überprüfen und zusätzlich 1 Komma pro Wert erlauben.

    Naja, du könntest folgendes machen (ungetestet)

    #include <stdbool.h>
    #include <stdlib.h>
    #include <assert.h>
    
    bool readfloat(float *f) {
      assert(f);
      char buf[255];
      if(!fgets(buf, sizeof(buf), stdin)) {
        return false;
      }
      char *endptr;
      *f = strtof(buf, &endptr);
      return *endptr == '\0';
    }
    

    btw. warum nutzt du überhaupt float? Standardmäßig sollte man lieber double benutzen, wegen der höheren Präzision.



  • Du kannst nach dem scanf auch noch den Rest des Eingabepuffers auslesen.
    Wie das geht steht bei: http://www.c-plusplus.net/forum/p1146014#1146014

    Du kannst auch mit fgets und strtod arbeiten. strtod gibt dir auch an, wo es nicht mehr weiterkommt.



  • rüdiger schrieb:

    #include <stdbool.h>
    
      *f = strtof(buf, &endptr);
      return *endptr == '\0';
    }
    

    stdbool und strtof sind nur C99, strtod ist ANSI C und genauso verwendbar.

    Ohne Überlaufsprüfung (die nur strtod macht) geht es auch mittels scanf z.B.

    float f;
    if( 1==scanf("%f",&f) && getchar()=='\n' )
      puts("OK");
    else
    {
      while( getchar()!='\n' );
      puts("kein korrekter Float-Wert");
    }
    

    Das 'Komma' ist hierbei übrigens defaultmäßig ein Punkt '.'.



  • Danke für die zahlreichen Beiträge und Lösungsansätze 🙂

    Ich hab die Format-Überprüfung jetzt mit dem Vorschlag von 'Wutz' realisiert, da mir dieser Weg am verständlichsten und kompaktesten vorkam - danke hierfür 😉

    Das Programm ist nun eigentlich fertig und tut das, was es soll 😃

    Falls irgendjemand Interesse am Felgen-/Einpresstiefen-Rechner hat, dann einfach 'ne PN an mich, dann bekommt er/sie die EXE-Datei gerne per Mail.

    MfG hofmanius

    PS: Kann mir jemand sagen, wie man das Icon einer EXE-Datei ändert bzw. kennt jemand ein geeignetes Programm hierfür?

    PPS: Hab das mit dem Icon schon geschafft 😉



  • Ich halte es für unwahrscheinlich, dass Du hier zahlreiche Abnehmer einer .exe-Datei findest 🙂



  • Stimmt, da könnte was Wahres dran sein 😃
    An das habe ich nicht gedacht...


Anmelden zum Antworten