Ubuntu Suomen keskustelualueet
Ubuntun käyttö => Ohjelmointi, palvelimet ja muu edistyneempi käyttö => Aiheen aloitti: 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.
#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
-
Vaikuttaa sittenkin siltä, että yllä olevan koodin tapaan pitää menetellä, ja sitten voi tehdä itse oman conio.h -jäljitelmän kuten alla
/*
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 ;)
-
Tässä on sitten vielä varmistukseksi toimiva ohjelma, käännöskomento on viimeisellä rivillä
#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