[*nix, C] Как получить нажатия кнопок?

lenok62

Мне нужна помощь по Си.
Что надо?:
-Надо чтобы программа останавливалась и при нажатии кпопки "f" делала работу А, а при нажатии кнопки "g" делала работу Б, если другая кнопка то джала и ничего не делала. Дело в том что я знаю как это сделать, но только в том случает если нажать кнопку "f" а потом Ентер(аналогично кнопка "g" потом Ентер а мне надо чтобы как только я нажал кнопку "f" или "g" уже всё работало(без Ентер).

okis

man getch

kruzer25

http://www.google.ru/search?hl=ru&source=hp&ie=windo...
Сможешь реагировать на любую клавишу, хоть Escape.

AlexV769

MS Windows only?

lenok62

Для него как я понял нужна библиотека conio.h . А я работаю на Убунте и такая библиотека не находится.

lenok62

vugar-laptop:~$ man getch
No manual entry for getch

barbos

$ sudo apt-get install ncurses-dev  

lenok62

Спасибо огромное, функция сработала!

lenok62

На такую программу
 #include <stdio.h>
#include <ncurses.h>

#define ESC_CODE 27
#define KEYB_UP 72
#define KEYB_DOWN 80

int main
{
char ch;

printf("Push up or down key, Esc to exit program.\n");

do
{
switch(ch=getch
{
case KEYB_UP:
printf("up\n");
break;
case KEYB_DOWN:
printf("down\n");
break;
}
}while(ch != ESC_CODE);

return 0;
}

Выдается такая ошибка:
 
vugar-laptop:~$ gcc pro.c
/tmp/cc8IAtr6.o: In function `main':
pro.c:(.text+0x1e): undefined reference to `stdscr'
pro.c:(.text+0x26): undefined reference to `wgetch'
collect2: ld returned 1 exit status
vugar-laptop:~$

Не могу понять в чем дело.

Dasar

либу соответствующую прилинковать

lenok62

В конце консоли конда компилировал добавил -lcurses
откомпилировалось, но пока не сработало.

istran

Нарыл POSIX-совместимое решение, не требующее сторонних библиотек:

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

int mygetch(void)
{
struct termios oldt, newt;
int ch;
tcgetattr( STDIN_FILENO, &oldt );
newt = oldt;
newt.c_lflag &= ~( ICANON | ECHO );
tcsetattr( STDIN_FILENO, TCSANOW, &newt );
ch = getchar;
tcsetattr( STDIN_FILENO, TCSANOW, &oldt );
return ch;
}

lenok62

code: #include <stdio.h>
#include <ncurses.h>
#define ESC_CODE 27
#define KEYB_UP 72
#define KEYB_DOWN 80
int main
{
char ch;

printf("Push up or down key, Esc to exit program.\n");
do
{
switch(ch=getch
{
case KEYB_UP:
printf("up\n");
break;
case KEYB_DOWN:
printf("down\n");
break;
}
}while(ch != ESC_CODE);

return 0;
}
vugar-laptop:~/programming$ ./pr
Push up or down key, Esc to exit program.
^[[A^[[A^[[B^[[B^[[B^[[C^[[C^[[D^[[D^[^[^[^[^[^[^[^[^C
vugar-laptop:~/programming$
Нажимаю кнопки вверх, вниз и esc а вместо них на теминале такое пишется: "^[[A" и т.д.

bleyman

По-моему, вы все какой-то фигнёй страдаете.
На стдин замечательно можно вызывать select и read.

zloDEY

поток от терминала буферизуется же
Some programs need an unbuffered terminal input stream. These include programs that read single-character commands (like Emacs) and programs that do their own input editing (such as those that use readline). In order to read a character at a time, it is not enough to turn off buffering in the input stream; you must also turn off input editing in the operating system. This requires changing the terminal mode (see section Terminal Modes). If you want to change the terminal modes, you have to do this separately--merely using an unbuffered stream does not change the modes.

там в приведенном куске как раз и меняется Terminal Mode

bleyman

А, ок, согласен.

lenok62

Еще один вопрос:
Вот на винде для функции getch при нажатии кнопки esc возвращает значение 27, при нажатии "вверх" возвращает 87.
А вот в линуксе никак не могу понять чему возвращается значение.
*надеюсь я смог ясно выразится.

Ivan8209

> А вот в линуксе никак не могу понять чему возвращается значение?
Несмотря на то, что в конце стоит вопросительный знак, это не вопрос.
---
Q6: Я слышал есть такой мужик, вроде Бармин зовут, и он
придумал что-то такое после чего XXX не сосет.

Dasar

А вот в линуксе никак не могу понять чему возвращается значение?
вставь printf("%d", (int)ch понажимай нужную кнопку, и посмотри что выводится
ps
для хитрых кнопок - там может быть два числа подряд, а не одно.

Ivan8209

> для хитрых кнопок - там может быть два числа подряд, а не одно.
Наивно.
---
A40: Так завещел великий и мудрый LT и по другому называть некошерно.

Ivan8209

> Нажимаю кнопки вверх, вниз и esc а вместо них на теминале такое пишется: "^[[A" и т.д.
man 5 termcap
---
"Vyroba umelych lidi, slecno, je tovarni tajemstvi."

lenok62

#include <stdio.h>
#include <ncurses.h>
int main
{
char ch,c1;
printf("Push any key\n");
for(;;)
{

ch = getch;
if( (int)ch != -1){
printf("%d", (int)ch);
}
}
return 0;
}
Вот такой странный результат:
vugar-laptop:~$ gcc -o vu vu.c -lncurses
vugar-laptop:~$ ./vu
Push any key
gghhhh knnvxm, mn,mn kkdvjkjyuef d xzzz z zz c v v d s a r f g gnbxcvufhskmc^C
vugar-laptop:~$
Эти буквы то что я нажимал ( xzzz z zz c v v d s a r f g gnbxcvuf).

okis

Вот такой странный результат:
Ты ожидаешь их коды?

lenok62

Да, но только не понимаю в чем ошибаюсь. Ночь, голова торомзит
вроде такая тоже ничего не делает:
int main
{
char ch,c1;

printf("Push any key\n");
do
{
c1 = ch;
ch = getch;
if(ch != c1){
printf("%d", (int)ch);
}
}while(1);

return 0;
}

pitrik2

Да, но только не понимаю в чем ошибаюсь.
ну ты как минимум забыл инициализировать ncurses
все методы что зовешь поэтому автоматом возвращают ошибку, в частности getch возвращает -1

initscr;

а вообще man ncurses тебе не помешает почитать
там же это прям в самом начале
To get character-at-a-time input without echoing (most interactive, screen oriented programs want this the following sequence
should be used:
initscr; cbreak; noecho;
Most programs would additionally use the sequence:
nonl;
intrflush(stdscr, FALSE);
keypad(stdscr, TRUE);

tokuchu

printf("%d", (int)ch);
Ты забыл про то, что STDOUT буферизуется.

lenok62

Вот программа сработала. Но результат совсем не то что надо. сейчас постараюсь все разяснить:
Вот эта программа полоностью без ошибок сработала
#include <ncurses.h>

int main
{
char ch,c1;
initscr;
cbreak ;
noecho ;

for(;;) {
ch = getch;
if( (int)ch != -1){
printf("%d\n", (int)ch);
}
}
endwin;
return 0;
}

Но дело в том что как только запускаю программу терминал становится чистым и пропадает все там было. нажимаю кпопку, ничего не печатается. нажимаю ctrl+c и тогда возвращается преждние вещи(то что попадало) + код кнопки которую я нажимал. Теперь в чем минус: Мне нужно чтобы ничего не терялось и когда я нажимал какую либо кнопку что-то там печаталось и главное было видно прямо(! когда нажимал другую клавишу печаталось что-то другое. А здесь пропадает все, как будто новый пустой терминал и то что печатается становится невидным пока программа не остановится.
Что-то можете посоветовать?

pitrik2

а уже спрашивали зачем тебе это надо?
просто тебе же дал посиксовское решение
чем оно те не подходит?
зачем ты на ncurses полез если его фишки тебе не нужны?
Оставить комментарий
Имя или ник:
Комментарий: