ESC- und Enter- Tasten abfangen



  • Hallo!

    ich möchte unter Linux (debian) ein Konsolenprogramm schreiben. Um Benutzereingaben entgegenzunehmen wollte ich eigentlich mit kbhit() und getch() die Zeichen einzeln einlesen und entsprechend reagieren. Allerdings gibt es die conio.h unter Linux nicht.
    Hat da jemand eine Lösung? ich versuche jetzt zwei kleine Programme zu schreiben:
    das erste solle dem Benutzer ermöglichen eine Wert eins Variables zuändern oder sein alte Wert zu behalten wenn er Entertaste drückt:

    char wahl;
      int b=10;
      cout<<"b="<<b<<endl;
    
      do{
        cout<< "Bitte geben Sie ein:"<<endl;
        cout<< "Taste a: ändern"<<endl;
        cout<< "Tase  Enter : alte Wert von b behalten "<<endl;
        cin>> wahl;
    
        switch(wahl){
    
        case 'a': 
          cout<<"Wert für b eingeben:"<<endl; 
          cin>>b;
          cout<<"neue Wert von b ist "<<b<<endl;
          break;
    
        case'VK_RETURN' :      
          b=b;   
          cout<<"b="<<b<<endl;
    
          break;
    
        default : 
          cout<<"falche eingabe"<<endl;
        }   
      }while((wahl =='a')||(wahl=='VK_RETURN'));
    
      return 0;
    }
    

    aber cin kann die sonder Zeichen nicht einlesen.

    mein zweite Programm soll beendet wird wenn die ESC Taste gedrückt wird:

    do{
      cin<<wahl;
      switch(wahl){
    
      case 'a' : 
        // anweisung
        break;
      case 'b':
        //anweisung
        break;
      case 'c':
        //Anweisung
        break;
      default:
        break;
      }while(wahl !=VK_ESCAPE);
    
     return 0;
    }
    

    hat jamend für mich eine Idee wie ich meine Programme zum laufen bringen kann.

    Danke schönmal im Voraus

    Gruß

    Seb



  • Ich bin mal so frei und verschiebe dich ins Linux-Forum 😉

    MfG SideWinder



  • Dieser Thread wurde von Moderator/in SideWinder aus dem Forum DOS und Win32-Konsole in das Forum Linux/Unix verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.



  • Die ncurses Bibliothek ist dein Freund, die gibt es übrigens auch für Windows (urspünglich aber Unix), da gibt es getch() Entsprechungen.
    VK_* u.ä. gibt es dort aber nicht in der Form.



  • die gibt es übrigens auch für Windows

    Wo gibts bitte ne gescheite Umsetzung für windows ?
    Meinst du PDCurses ?
    oder das ich nen halbes linux integrieren muss (cygwin) ?

    Ciao ...



  • Was hast du an der getch() Umsetzung von PDcurses auszusetzen?
    Und Public Domain ist sie auch noch wie der Namen sagt.



  • Was hast du an der getch() Umsetzung von PDcurses auszusetzen?

    Hab die nie zum laufen bekommen ... aber wahrscheinlich war ich ned energisch genug 🙂 Und ueber die Sinnigkeit von curses anwendungen unter windows kann man immer noch streiten ...

    trotzdem find ich auch wegen nem VK_RETURN Ersatz die Curses einzubinden, bissi uebertrieben 🙂

    entweder nutzt er streams, dann muss er auch mit leben, das das enter nicht auf das getchar mappt, muss er halt was anderes nehmen.

    Oder er macht ne richtige Halbgrafik (also menu und pseudo fensterbasierend) dann macht auch die curses Sinn

    oder er beschaeftigt sich mit Terminals, und merkt was geht und was ned und wie man tasten da abfangen kann ...

    Alles andere ist irgendwie weder Fisch noch Fleisch ...

    Ciao ...



  • Hallo leute !
    könnte nicht weiter kommen!
    kann mir da jemend helfen oder ein Beispiel mal posten
    wie mein Aufgabe lösen kann

    
    

    do{
      cin<<wahl;
      switch(wahl){

    case 'a' :
        // anweisung
        break;
      case 'b':
        //anweisung
        break;
      case 'c':
        //Anweisung
        break;
      default:
        break;
      }while(wahl !=VK_ESCAPE);

    return 0;
    }



  • Jetzt stell dich mal nicht so an.
    Nehme

    #include <ncurses.h>
    

    rein, schaue dir die Spezifikation dazu an, compiliere mit -lcurses und fertig.



  • danke schön mal
    habe ich versucht eber hat leider nicht geklappt



  • @Wutz bei diesem Exemplar darfst es Dir auch ned sooo einfach machen 🙂
    Die Spezifikation anschauen langt eben nicht.
    Er muss auch Änderungen in seinem Quellcode vornehmen. +
    Das haettest Ihm sagen muessen 🤡

    @sebleb

    cin<<wahl;
    

    nen Textbasierter Stream, dazu gehoert auch std::cin, wird dir nie nen "Escape" Zeichen liefern, weil "Escape" Zeichen existieren nicht in einer rohen Form.
    (In nem Terminal kann man nen Zeichen zum Escape Zeichen machen, das ist aber ne andere gechichte)
    ergo: Stream nix Escape, weil Escape Taste und nix Zeichen !

    Du darfst Dir also nicht den EingabeStrom als Quelle deiner Eingaben fuer den Fall hernehmen, sondern muesstest Tastatur-Anschlage abfangen ...
    und den Tip nach was zu suchen hasst ... hat dir Wutz auch gegeben



  • Ich habe hier mal was Lauffähiges für Unix zusammengegoogelt (ohne ncurses!).

    http://www.ideone.com/Hoqql

    Das ist alles C und für Unix, aber dafür läuft es wenigstens sofort. Deine Umsetzung für C++ iostreams musst du schon selbst machen.

    ncurses und Standardeingabeeingaben kurz erklärt gibt es z.B. hier:

    http://www.linuxselfhelp.com/HOWTO/NCURSES-Programming-HOWTO/keys.html



  • Wutz schrieb:

    Ich habe hier mal was Lauffähiges für Unix zusammengegoogelt (ohne ncurses!).

    http://www.ideone.com/Hoqql

    Der Code ist sehr interessant, verbrät aber viel CPU Leistung wegen

    while( kbhit() );
    

    Da Linux ein Multiuser OS ist sollte es eine bessere Lösung (Eventhandler ?)
    geben, der den Prozess schlafen legt solange es nichts zu tun gibt.

    Notfalls hilft hier ein sleep um das abzumildern ...

    Sonderzeichen inklusive Zeilenendezeichen bekommt man mit ANSI-C doch
    einfach mit getch() oder mit fgetc() oder fgets().

    Hier mal ein Beispiel mit fgets:

    #include <stdio.h>
    
    main()
    {
      char buff[80];	/* Input buffer */
    
      /* Get data from the keyboard */
      printf("Eingabe => ");
      fgets(buff, sizeof(buff), stdin);
    
      printf("\nlength is %d #%s#\n\n",strlen(buff),  buff);
    }
    


  • merano schrieb:

    Sonderzeichen inklusive Zeilenendezeichen bekommt man mit ANSI-C doch
    einfach mit getch() oder mit fgetc() oder fgets().

    getch() ist eben kein ANSI C, deswegen doch dieser ganze Aufwand.



  • Wutz schrieb:

    getch() ist eben kein ANSI C, deswegen doch dieser ganze Aufwand.

    Den Aufwand kannst du dir mit dieser Einstellung gleich mal sparen:

    Bei <stdio.h> handelt es sich um eine Standard-Bibliothek,
    die im ANSI-Standard definiert ist (Kernghan/Ritchie ).

    Ein- und Ausgabe sind generell nicht als Teil der Sprache C
    selbst definiert. Da kommt man also auf diesem formalen Weg
    nicht weiter.

    Wenn man also ohnehin eine Bibliothek braucht macht es Sinn eine
    zu nehmen, die auf möglichst vielen Systemen ohnehin vorhanden
    ist - eben eine ANSI Standard-Bibliothek.

    Deine vorgeschlagene ncurses ist das übrigens nicht ...

    Wenn man aber <stdio.h> akzeptiert ..

    Siehe auch:

    The ANSI-C Standard Library - Contents

    http://www.csse.uwa.edu.au/programming/ansic-library.html

    ANSI-C Dateiverarbeitung

    http://info.baeumle-courth.eu/c09.html

    An Grundsatzdiskussionen bin ich nicht interessiert. Wer den Vorschlag nicht
    mag kann es gerne auch anders lösen 🤡



  • Sonderzeichen inklusive Zeilenendezeichen bekommt man mit ANSI-C doch
    einfach mit getch() oder mit fgetc() oder fgets().

    ja, wobei ein geth() nix anderes ist als wie cin.getc() !

    Nun bleibt die Frage, was sind Sonderzeichen ? und wie kommen sie in einen Text-Datenstrom.
    Mit "Enter" wird es z.b. schon schwierig ... ein tastendruck auf der Console -> mal wird ein Zeilen-Endezeichen eingefügt, mal wird einfach nur die EIngabe als beendet angesehen ....
    also mal sieht man nen enter in form eines zeilenendezeichens, mal nicht je nachdem wie man einfuegt und auswertet.
    Und WIndows verwendet andere zeilenende-zeichen als Linux z.b.

    keine Tolle Loesung oder ?

    Noch schlimmer das Escape. Es bewirkt auf den Datenstrom, also dein cin gar nix, stattdessen muss das terminal irgendwie reagieren.

    Und eigentlich ist es kein "gutes verhalten" fuer ein Konsolebasierendes Programm, wenn es mit cin,cout und co ned weiterkommt. Also entweder verlaesst man die Kompatible Konsolenschiene, oder man bleibt Konsolen - kompatibel, dann reagiert man aber auch auf Textdarstellbare Zeichen ...

    Also Fazit:
    Standard Eingabe - Ausgabe (stdio) bezieht sich nur auf textbasierte Datenstroeme, deren Standard Interfaces (cin,cout,cerr) und dateien.

    Willst du Tastaturanschlaege abfangen, die nicht in Textbasierende Datenstroeme passen, kommst du mit ANSI Irgendwas gar nicht weiter.

    DU musst auf deine Plattform. Plattformspezifische Bibliothen sind beispielsweisse Posix/SystemV(Unix und co) und WinAPI ...

    Dort findest du auch entsprechende Einsprungpunkte zu dem entsprechenden Thema's (terminal IO bei Unix & co, bzw. Tastatur funktionen / hooks in der WinAPI).

    Oder du verwendest 3d Party Libs (ncurses z.b.)

    Ciao ...



  • Hallo Jungs!
    bin wieder zurück; meine Aufgabe hat sich ein bisschen geänder:
    In der Konsole soll man die Werte von Variable von typ double entwender ändern
    oder mit Enter -taste seine alte Werte behalten.Für den Fall, dass statt einer Zahl irgendwas falsches z.B.: Buchstaben eingegeben werden, soll ne Fehlermeldung mit erneuter eingabe folgen.
    um Enter taste zu emfangen habe ich ncurses Library verwendet aber leider
    konnte es nicht zum laufen kriegen , hier ist meine Versuche:

    double b =10.07;
    
    cout<<"b="<<b<<endl;
    
      do{
        cout<< "Bitte geben Sie ein:"<<endl;
        cout<< "Taste a: ändern"<<endl;
        cout<< "Tase  Enter : alte Wert von b behalten "<<endl;
        int  wahl=getch();
    
        switch(wahl){
    
        case 48:
          do{
          cout<<"Wert für b eingeben:"<<endl;
            if(!(cin >> b)){
          cout<<"Falche Eingabe! Zahl neu eingeben:"<<b<<endl;
           }
           }while(!b);
          break;
    
        case KEY_ENTER :      
          b=b;  
          cout<<"b="<<b<<endl;
          break;
    
        default : cout<< "falche Eingabe"<<endl;
        }  
      }while((wahl ==48)||(wahl==KEY_ENTER)); 
    
     cout<<"b="<<b<<endl;
    

    kann mir da jemand weiterhelfen.

    Beste danke


Anmelden zum Antworten