C Konsolenprogramm mit einer bestimmte Taste beenden



  • Hallo zusammen,

    vorab: Ich bin totaler Anfänger und mein Kenntnisstand ist noch ziemlich schlecht

    Ich sitze nun seit 2 Tagen an dem gleichen Problem und fange langsam an zu verzweifeln.

    Ich versuche ein einfaches Programm zu schreiben, welches mir Zahlen von 0 bis 999 in ihre Dezimalstellen zerlegt. So weit funktioniert es aber ich würde gerne durch eine bestimmte Taste das Programm beenden können. Zum Beispiel nachdem das Programm einmal durchlaufen ist möchte ich, dass es sich mit der Taste X beenden lässt. Am besten auch noch ohne, dass ich mit Enter bestätigen muss.

    Habe viel darüber gelesen, dass es mit Strings oder Arrays(hatten wir aber noch nicht im Sudium) machbar ist, dennoch hab ich es nicht hinbekommen. Außerdem ist dies eine kleine Übung des ersten Semesters und der Prof sagte, die Lösung wäre ziemlich einfach.

    Freue mich über jede Hilfe. Gerne kann auch der Code verbessert werden, denn ich in mir sicher das geht auch schöner.

    #include <stdio.h>
    #include <stdlib.h>
    
    int main()
    {
    	int zZahl = 0;
    	int zHunderter = 0;
    	int zZehner = 0;
    	int zEiner = 0;
    
    	printf("Geben Sie eine ganze Zahl von 0 bis 999 ein: ");
    	scanf_s("%d", &zZahl);
    
    	if (zZahl < 0 || zZahl > 999)
    	{
    		printf("Eingabe ungueltig! Bitte Wiederholen.\n");
    		main();
    	}
        else if (zZahl >= 0 || zZahl <= 999)
    	{
    		zHunderter = zZahl / 100;
    		zZehner = (zZahl - (zHunderter * 100))/ 10;
    		zEiner = zZahl - (zHunderter * 100) - (zZehner * 10);
    
    		printf("Die eingegebene Zahl %d besitzt:\n", zZahl);
    		printf("%d Hunderterstelle(n)\n", zHunderter);
    		printf("%d Zehnerstelle(n)\n", zZehner);
    		printf("%d Einerstelle(n)\n", zEiner);
    		main();
    	}
    	return 0;
    }
    


  • scanf_s() ist bei mir nicht deklariert, habe stattdessen scanf() verwendet. http://www.cplusplus.com/reference/cstdio/scanf/?kw=scanf
    scanf() gibt bei ungültiger Eingabe oder einem Stream-Lese-Fehler nicht die erwartete Anzahl der Argumente zurück. Dies kann zum Beenden des Programms ausgenutzt werden, sofern z.B. anstatt einer erwarteten Zahl irgendein Buchstabe eingegeben werden darf. Jedoch muß dann immer noch <Enter> gedrückt werden. Beispiel ohne Berücksichtigung von errno, feof, ferror o.a.:

    #include <stdio.h>
    #include <stdlib.h>
    #include <stdbool.h>
    
    int main()
    {
        const int iScanfArgs = 1; // Anzahl scanf-Argumente
        int zZahl, iChar, bExit, iScanf;
    
        do {
            printf("Geben Sie eine ganze Zahl ein: ");
            bExit = false;
            iScanf = scanf("%d", &zZahl);
            if (iScanf == iScanfArgs) {
                //... Funktionen des Hauptteils
                printf("Ihre Eingabe: %d. Weiter im Programm.\n", zZahl);
            } else {
                //nach ungültiger Eingabe Streampuffer leeren:
                do {
                    iChar = getchar();
                    if ('X' == ((char) iChar))
                        bExit = true; //hier noch kein return 0;
                } while ('\n' != ((char) iChar));
                if (false == bExit) printf("Eingabe ungueltig!\n");
            }
        } while (false == bExit);
        return 0;
    }
    

    Wenn das Programm erst am Ende von main() nach Tastendruck beendet werden soll, kann getch() zur Tastaturabfrage verwendet werden (solcher Code soll aber vermieden werden, siehe unten).

    #include <stdio.h>
    #include <stdlib.h>
    #include <conio.h>
    
    int getkeybd()
    {
    // Tastaturabfrage mit getch() oder getche() aus <conio.h>:
    // Normale (ASCII-)Zeichen liefern 1-Byte-Tastencodes 0...255.
    // Falls eine Taste eines 2-Byte-Tastencode gedrückt wurde, dann
    // muß auch das 2. Byte aus dem Tastaturpuffer gelesen werden,
    // sonst kann es zu unerwünschten Effekten im Programm kommen.
    // 2-Byte-Tastencodes liefern z.B. F1...F10 oder Pfeiltasten.
    // Das 1. Byte hat den Wert 0 oder 224, je nach dem, ob die
    // Taste dem normalen Tastaturfeld oder einem Ziffernblock o.a.
    // zugeordnet ist. Das 2. Byte liefert den Scancode der Taste.
        int i;
        i = getch();
        if ((0 == i) || (224 == i)) i = (i & 255) | (getch() << 8);
        return i;
    }
    
    int main()
    {
        do {
            //... Hauptteil
        } while ('X' != ((char) getkeybd()));
        return 0;
    }
    

    Von solchem Code wird aber auch abgeraten: https://www.c-plusplus.net/forum/39320-full
    Schließen der Konsole verhindern (C und C++): https://www.c-plusplus.net/forum/111042
    Warum system("pause"); nicht verwenden: https://www.c-plusplus.net/forum/39453



  • Lass das mit dem rekursiven Aufruf von main() sein.

    Dafür gibt es Schleifen!

    Und dann reicht es, wenn du den Rückgabewert von scanf auswertest.

    if (1 != scanf("%d", &zZahl)) 
    {
      hier  Fehlerbehandlung (z.B. ein break; für den Anfang)
    }
    

    Dafür ist zwar immer noch das Enter am Ende der Eingabe nötig, aber du brauchst keine nervige Abfrage wie "Wollen Sie nochmal?"

    Mehr zu scanf: http://www.cplusplus.com/reference/cstdio/scanf/

    Eine Tastatur kennt C erstmal nicht, daher sind Abfragen auf Tasten systemabhängig.

    Auch die Dezimalstellenzerlegung kann man mit einer Schleife machen. Dafür ist der Modulo-Operator % sehr hilfreich.



  • Vielen Dank für die ausführlichen Antworten. Hat mir sehr geholfen und bin nun um einiges schlauer und das noch rechtzeitig zum Vorführtermin am Freitag.

    Danke!


Log in to reply