Kirjoittaja Aihe: [ ratkaistu ] C++ näppäimistöpainalluksen havaitseminen  (Luettu 2089 kertaa)

teele

  • Käyttäjä
  • Viestejä: 852
    • Profiili
Miten pitäisi tehdä ohjelma, joka toimii muuten itsenäisesti, mutta havaitsee, jos jotain näppäintä on painettu. Ohjelmassa ei haluttaisi pysähtyä odottamaan, tuleeko merkki vai ei kovin pitkäksi aikaa. Tavalliset syötekomennot jäävät sitä paitsi odottamaan enteriä.

Löysin verkosta seuraavan ohjelman, mutta onkohan se vähän liian monimutkainen näin yksinkertaiselta näyttävään kysymykseen. Ainakin siinä tehdään kaksinkertainen työ, kun luettu merkki kirjoitetaan takaisin lukupuskuriin, ja tämän lisäksi asetellaan edestakaisin termios-rakenteen parametreja.

Koodia: [Valitse]
#include <termios.h>
#include <unistd.h>
#include <fcntl.h>
int kbhit(void)
{
  struct termios oldt, newt;
  int ch;
  int oldf;

  tcgetattr(STDIN_FILENO, &oldt);
  newt = oldt;
  newt.c_lflag &= ~(ICANON | ECHO);
  tcsetattr(STDIN_FILENO, TCSANOW, &newt);
  oldf = fcntl(STDIN_FILENO, F_GETFL, 0);
  fcntl(STDIN_FILENO, F_SETFL, oldf | O_NONBLOCK);

  ch = getchar();

  tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
  fcntl(STDIN_FILENO, F_SETFL, oldf);

  if(ch != EOF)
  {
    ungetc(ch, stdin);
    return 1;
  }

  return 0;
}

lähde: http://stackoverflow.com/questions/22166074/is-there-a-way-to-detect-if-a-key-has-been-pressed


« Viimeksi muokattu: 30.08.16 - klo:11.10 kirjoittanut teele »

teele

  • Käyttäjä
  • Viestejä: 852
    • Profiili
Vs: C++ näppäimistöpainalluksen havaitseminen
« Vastaus #1 : 30.08.16 - klo:11.09 »
Vaikuttaa sittenkin siltä, että yllä olevan koodin tapaan pitää menetellä, ja sitten voi tehdä itse oman conio.h -jäljitelmän kuten alla

Koodia: [Valitse]
    /*
    AUTHOR: zobayer
    INSTRUCTION:
    just make this file a header like "conio.h"
    and use the getch() and getche() functions.
    */
    #include <termios.h>
    #include <unistd.h>
    #include <stdio.h>
     
    /* reads from keypress, doesn't echo */
    int getch(void) {
        struct termios oldattr, newattr;
        int ch;
        tcgetattr( STDIN_FILENO, &oldattr );
        newattr = oldattr;
        newattr.c_lflag &= ~( ICANON | ECHO );
        tcsetattr( STDIN_FILENO, TCSANOW, &newattr );
        ch = getchar();
        tcsetattr( STDIN_FILENO, TCSANOW, &oldattr );
        return ch;
    }
     
    /* reads from keypress, and echoes */
    int getche(void) {
        struct termios oldattr, newattr;
        int ch;
        tcgetattr( STDIN_FILENO, &oldattr );
        newattr = oldattr;
        newattr.c_lflag &= ~( ICANON );
        tcsetattr( STDIN_FILENO, TCSANOW, &newattr );
        ch = getchar();
        tcsetattr( STDIN_FILENO, TCSANOW, &oldattr );
        return ch;
    }


lähde: http://zobayer.blogspot.fi/2010/12/getch-getche-in-gccg.html

Luulisin, että näillä ratkeaa ja merkkaan tämän rohkeasti ratkaistuksi, vaikka en vielä ole ehtinyt kokeilla  ;)
« Viimeksi muokattu: 30.08.16 - klo:11.11 kirjoittanut teele »

teele

  • Käyttäjä
  • Viestejä: 852
    • Profiili
Vs: [ ratkaistu ] C++ näppäimistöpainalluksen havaitseminen
« Vastaus #2 : 13.09.16 - klo:21.37 »
Tässä on sitten vielä varmistukseksi toimiva ohjelma, käännöskomento on viimeisellä rivillä


Koodia: [Valitse]

#include <termios.h>
#include <unistd.h>
#include <fcntl.h>

#include <stdio.h>  // getchar, unget, EOF
#include <iostream>



int oma_getch()
{
        //char buf = 0;
        int buf = 0;
        struct termios old = {0};
        if (tcgetattr(0, &old) < 0)
                perror("tcsetattr()");
        old.c_lflag &= ~ICANON;
        old.c_lflag &= ~ECHO;
        old.c_cc[VMIN] = 1;
        old.c_cc[VTIME] = 0;
        if (tcsetattr(0, TCSANOW, &old) < 0)
                perror("tcsetattr ICANON");
        if (read(0, &buf, 1) < 0)
                perror ("read()");
        old.c_lflag |= ICANON;
        old.c_lflag |= ECHO;
        if (tcsetattr(0, TCSADRAIN, &old) < 0)
                perror ("tcsetattr ~ICANON");
        return (buf);
}



int main()
{
  int i = 0;
  while(1)
  {
    oma_getch();
    i++;
    std::cout << "luettiin merkki " << i << "  " << std::endl;
  }

}


// g++ koe.cpp -o koe -Wall -pedantic -L/usr/local/lib -lserial  -std=c++11 


lähde:
http://stackoverflow.com/questions/421860/capture-characters-from-standard-input-without-waiting-for-enter-to-be-pressed
« Viimeksi muokattu: 17.09.16 - klo:11.56 kirjoittanut teele »