Schleife unterbrechen



  • Hallo,

    folgendes Problem,

    wie kann ich eine for-Schleife ablaufen lassen und in der schleife auf eine Taste reagieren?

    Die Schleife läuft selbständig ab z.B. 100 mal, aber wenn ich dazwischen über eine Taste abbrechen will, wie mache ich das?? Bei getche oder getchar bleibt die Schleife immer stehen und wartet auf die Eingabe, ich will aber nur auf eine Eingabe reagieren.

    Danke für die Hilfe.

    Gruß
    Frostie



  • Strg-Alt-C



  • Ich glaub mit ANSI-C lässt sich da nicht viel machen. Wenn du unter Windows arbeitest try this:

    #include <iostream>
    #include <string>
    #include <conio.h>
    using namespace std;
    
    int main()
    {
            int input = 0;
            for(unsigned int i = 0; i < 10000000; ++i)
            {
                    input = getch();
                    if((char)input == 'e') // Für exit ;)
                    {
                            cout << "\n Schleife wird unterbrochen, da e gedrueckt wurde\n";
                            break;
                    }
            }
            return 0;
    }
    

    Unter Linux musst du dir mal nrcurses.h o.ä. anschauen.

    Caipi



  • Tolle Antwort, aber erstens ist es Strg+C ohne Alt und ausserdem sollte der Vorgang definiert beendet werden.

    Frostie



  • Danke Caipi,

    is es aber auch nicht ganz, da die schleife bei jedem Durchgang stehen bleibt und eine Eingabe erwartet.

    Die Eingabe sollte aber in Hintergrund ablaufen.

    Frostie



  • frostie schrieb:

    Tolle Antwort, aber erstens ist es Strg+C ohne Alt und ausserdem sollte der Vorgang definiert beendet werden.

    Du kannst das kanonische Verhalten von Ctrl-C usw. schön ändern (Signalhandler). Wollen tut man das aber nicht allzu oft und ich denke, sowas suchst Du auch nicht.



  • das würd mich aber so mal interessieren, wie geht das genau?

    Frostie



  • Du könntest kbhit() verwenden, das überprüft nichtblockierend auf vorhandene Zeichen im Buffer. Dabei musst du nur beachten, dass die Zeichen nicht aus dem Buffer entfernt werden, du könntest es dann mit getch() abrufen, das dann ja nicht mehr blockieren würde, da ja ein Zeichen im Buffer vorhanden ist. Ist allerdings nicht ANSI C.

    EDIT:

    for (int i=0;i<100000000;i++) {
        if (kbhit()) {
            getch();
            printf("%i",i);
            break;
        }
    }
    


  • Ich denke du suchst etwas wie z.B. _kbhit(). Das ist alllerdings eine Funktion die nicht zum Standard gehört. Unter Borland heisst sie imho kbhit() (ohne underscore).

    Edit: Und wieder mal zu langsam... 😕



  • Hallo,

    danke,

    genau das war es, was ich suchte.

    Frostie



  • Für den Fall, dass du ne Lösung willst, die nicht 100% CPU-Last frisst, dafür aber etwas komplexer ist, mit POSIX-Threads sähe das so aus:

    #include <pthread.h>
    #include <stdio.h>
    #include <unistd.h>
    
    void *run_loop(void *arg_ptr) {
      int i;
    
      for(i = 0; i < 100; ++i) {
        /* Hier den Code einfügen, der 100 mal ausgeführt werden soll */
        printf("%d\n", i);
        sleep(1);
      }
    
      return NULL;
    }
    
    void *interrupt_on_user_input(void *arg_ptr) {
      getchar();
    
      pthread_cancel(*((pthread_t*) arg_ptr));
    
      return NULL;
    }
    
    int main(void) {
      pthread_t loop_th, int_th;
    
      puts("ENTER zum Abbrechen.\n");
    
      pthread_create(&loop_th, NULL, &run_loop               , NULL            );
      pthread_create(& int_th, NULL, &interrupt_on_user_input, (void*) &loop_th);
    
      pthread_join(loop_th, NULL);
    
      pthread_cancel(int_th);
    
      return 0;
    }
    

    Für einfachen Code in der Schleife reicht das so, wenn du allerdings komplexeren Code hast, der nachher ein cleanup erfordert, solltest du dir pthread_cleanup_push mal ankucken, damit kannst du handler einbauen, die ausgeführt werden, sobald der thread beendet wird. Das ist insbesondere dann interessant, wenn du in der Schleife Speicher per malloc anforderst oder Dateien öffnest oder irgendwelche anderen Ressourcen anforderst, die du von Hand wieder freigeben musst.



  • Wieso sollten durch mehrere Threads weniger CPU-Last erzeugt werden als mit einem? Kbhit blockiert ja nicht, damit ist es doch auch nicht nötig, das in einen anderen Thread auszulagern. Außerdem liest getchar() gepuffert mit echo und erwartet Enter zur Bestätigung der Eingabe. getch() hingegen liest ein Zeichen ungepuffert ohne echo.


Anmelden zum Antworten