Kleine Frage zu Scanf



  • Guten Morgen, liebe Community. 🙂 Da bin ich auch schon wieder.

    Ich bin immer noch bei meinem Handbuch, aber ich habe mal eine kleine Fingerübung abseits davon gewagt. Ich habe mal einen obligatorischen kleinen Taschenrechner geschrieben, aber jetzt habe ich ein Problem..!

    #include <stdio.h> 
    #include <stdlib.h> 
    
    //     Funktion für die Rechnung
    int mathe (char opera, int zahl1, int zahl2) { 
    // Abschnitt fuer Plus 
        if (opera == '+') { 
        return (zahl1 + zahl2); 
        //Abschnitt fuer Minus 
    }else if (opera == '-') {  
        return (zahl1 - zahl2); 
        //Abschnitt fuer Multi 
        }else if (opera == '*') { 
        return (zahl1 * zahl2); 
        //Abschnitt fuer Divi
        }else if (opera == '/') {  
        return (zahl1 / zahl2); 
    }else { 
          printf ("Sie haben kein gueltiges Zeichen eingegeben.");
    }
    }
    
    int main () 
    { 
        char opera;
        int eingabe1, eingabe2, ergebnis;
        printf ("Gib die erste Zahl ein:\n"); 
        scanf ("%d", &eingabe1); 
        printf ("Gib die zweite Zahl ein:\n"); 
        scanf ("%d", &eingabe2); 
        printf ("\n\nGib deinen mathematischen Operatoren ein! (+),(-),(/), (*).\n");
        scanf ("%c", &opera); 
        ergebnis = mathe(opera, eingabe1, eingabe2); 
        printf ("\nDas Ergebnis ist %d.\n", ergebnis); 
        system ("PAUSE"); 
        return 0; 
    }
    

    Das Problem an dem Programm ist, dass es die Eingabe meines Operatoren komplett überspringt. Es fragt nach der ersten Zahl: Ich gebe ein. Es fragt nach der zweiten Zahl: Ich gebe ein. Statt auf die Eingabe des Operatoren zu warten, gibt er mir jedoch direkt "Sie haben kein gültiges Zeichen ausgegeben" aus. (Was logisch ist, denn ich hatte keine Gelegenheit zu einer Eingabe) Stattdessen bekomme ich irgendeinen zufälligen Wert aus. (Was ja auch der Fall sein müsste, da ich den Wert der Variable ergebnis nicht fest gelegt habe)

    Ich habe mal gelesen, dass der Speicher der Tastatureingabe manchmal erst geleert werden muss? Davon sagt mein Handbuch leider nichts. Oder liegt der Fehler hier einfach wieder bei mir?



  • Ah, das Thema hat sich schon erledigt. 😃 Gerade den entsprechenden Befehl in einem anderen Thema dieses Forums gefunden: fflush(stdin);

    Und tatsächlich: Damit funktioniert's. Cowabunga!



  • Dann schau mal in die FAQ zu dem Unterforum:
    flush(stdin)

    Oder warte einfach auf die Kommentare hier.

    Hat jemand Popcorn?



  • Veyrne schrieb:

    Ah, das Thema hat sich schon erledigt. 😃 Gerade den entsprechenden Befehl in einem anderen Thema dieses Forums gefunden: fflush(stdin);

    Und tatsächlich: Damit funktioniert's. Cowabunga!

    fflush(stdin) ist eigentlich böse und erzeugt undefiniertes Verhalten! Falls du den Microsoft-Compiler benutzt, ist es allerdings tatsächlich legal (dann aber nicht mehr portabel). Ansonsten schau dich doch bitte noch mal im Forum um (suche nach "Eingabepuffer leeren", dann findest du einiges).



  • fflush ist halt nicht für stdin gedacht, sondern für Output / update oder weiß der Geier was... (knows the vulture!)

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

    -> Das ist die Variante für Deinen Operator

    Um Dir eine Eingabe ordentlich zu speichern, die länger als 1 char ist, bietet sich ein char Array und eine kleine Modifikation der Schleife an. Das schaffst Du sicher selbst 🙂



  • DirkB schrieb:

    Oder warte einfach auf die Kommentare hier.

    Hat jemand Popcorn?

    😃 👍



  • Verdammt. Hätte ich doch geahnt, dass dieser Befehl ein Werk Satans ist. Jetzt dreht sich mein Monitor ohne sichtbare Fremdeinwirkung um die eigene Achse. 😉

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

    Ich werd' es mal mit dieser Methode versuchen. 🙂 Allerdings wird das wohl seine Zeit brauchen, da mir der Code teilweise nicht so verständlich ist, dass ich ihn logisch erschließen und damit behalten kann. 🙂 Leider scheint es auch keine wesentlich elegantere Lösung zu geben. (WinAPI dafür aufrufen!? WTF?)



  • Das würde ich Dir schon gerne erklären, ich habe nur gerade das Gefühl, dass Dich diese Codezeile direkt ins Nichts führt.

    Hab das Ganze auch nur aus dem FAQ kopiert, ohne drüber nachzudenken.

    Gewünscht hätte ich mir, dass Du am Ende in der Variable c das letzte eingegebene Zeichen vor der Eingabetaste hättest und die Eingabetaste nicht im Puffer rumschwimmt.

    Mit der Codezeile hast Du höchstwahrscheinlich am Ende schön das NewLine in c stehen und schaust sonst nur etwas verdutzt, wo denn die Eingabe ist...
    Diese Codezeile führt einfach nur dazu, dass der Eingabepuffer geleert ist und zwar bis inklusive des nächsten Zeilenumbruchs. Schönes Ding, bringt Dir aber keine sinnvoll gefüllte Variable.

    int c, inp;
    while ((c = getchar()) != EOF && c!= '\n')
    {
       inp = c;
    }
    

    Damit hast Du das letzte vor dem \n (Enter) eingegebene Zeichen in der Variable inp (in Form eines Integers -> z.B. inp == 50 für eine eingegebene '2') gespeichert.

    Wenn Du Lust auf mehr hast, benötigst Du ein entsprechendes Char-Array:

    int c, zahl1, zaehl = 0;
    char input[10];
    while ((c = getchar()) != EOF && c!= '\n')
    {
       input[zaehl] = c;
       zaehl++;
    }
    input[zaehl] = '\0';
    zahl1 = atoi (input);
    


  • Versuch doch mal beim scanf vor und/oder nach der Formatangabe ein Leerzeichen mit anzugeben. Das Leerzeichen überliest alle Arten von nicht druckbaren Zeichen wie Tabulator, '\n' oder ' '

    scanf(" %d ", &zahl);
    // oder
    scanf("%d ", &zahl);
    

    Evtl. reicht das schon.



  • PrettyP schrieb:

    Mit der Codezeile hast Du höchstwahrscheinlich am Ende schön das NewLine in c stehen und schaust sonst nur etwas verdutzt, wo denn die Eingabe ist...
    Diese Codezeile führt einfach nur dazu, dass der Eingabepuffer geleert ist und zwar bis inklusive des nächsten Zeilenumbruchs. Schönes Ding, bringt Dir aber keine sinnvoll gefüllte Variable.

    Das ist ja auch nicht der Sinn dieser Codezeile. Die sollst du vor jeder Benutzereingabe ausführen, damit der Eingabepuffer geleert ist und du auch eine vernünftige Eingabe bekommst. Das Ganze kann man sich z.B. in eine Funktion packen und dann ganz routiniert immer vor jeder Eingabe ausführen. Damit erübrigen sich auch Versuche der Umformulierung, um in diese (eigentlich temporäre) Variable was Sinnvolles 'reinzubekommen.



  • printf("\n[%d][%d][%d]\n", eingabe1, eingabe2, opera);
        system ("PAUSE");
    

    zum Schluss
    ist die dritte Zahl eine 10 Gratulation
    dann ist dein Operator deine Enter taste

    möchtest du das nicht
    so geht die Enter Taste in die variable temp

    scanf ("%d", &eingabe1); 
    scanf ("%c", &temp);
    
    scanf ("%d", &eingabe2);
    scanf ("%c", &temp);
    
    scanf ("%c", &opera);
    scanf ("%c", &temp);
    

Anmelden zum Antworten