Ubuntu Suomen keskustelualueet

Ubuntun käyttö => Ohjelmointi, palvelimet ja muu edistyneempi käyttö => Aiheen aloitti: teele - 30.08.16 - klo:10.06

Otsikko: [ ratkaistu ] C++ näppäimistöpainalluksen havaitseminen
Kirjoitti: teele - 30.08.16 - klo:10.06
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


Otsikko: Vs: C++ näppäimistöpainalluksen havaitseminen
Kirjoitti: teele - 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  ;)
Otsikko: Vs: [ ratkaistu ] C++ näppäimistöpainalluksen havaitseminen
Kirjoitti: teele - 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