Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Есть ли в Linux аналог функции getch() из библиотеки conio  (Прочитано 52032 раз)
0 Пользователей и 1 Гость смотрят эту тему.
andrystepa
Помогающий

ru
Offline Offline

« : 20-09-2006 05:19 » 

В консольной программе необходимо реагировать на нажатия клавиш. Тот код, что я использовал под виндами - функция getch() не проходит, так как компилятор не может найти заголовочного файла conio.h - да и я сам в полностью установленных ОС Mandriva Linux 2006 и Fedora Core 5 его не могу найти! Пробовал использовать библиотеку ncurses, но там перед вызовом getch() надо обязательно вызывать initscr(), которая, как я понял, фактически создает новую консоль. В этой новой консоли как-то по-другому работает оператор вывода в стандартный поток >>. Чем можно заменить?
Записан
RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #1 : 20-09-2006 07:35 » 

Хм. Есть стандартные C ф-ии getchar() и getc(FILE).
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #2 : 20-09-2006 12:42 » 

Практически все стандартные функции описываются тут http://www.gnu.org/software/libc/manual/html_node/index.html
Записан

Не будите спашяго дракона.
             Джаффар (Коша)
andrystepa
Помогающий

ru
Offline Offline

« Ответ #3 : 20-09-2006 15:29 » 

Да, но только эти функции ждут нажатия пользователем клавиши Enter. Если используешь управление в программе клавишами стрелок или +-, или любыми другими это, мягко говоря, неудобно. Попробуйте ка поиграть в DOOM если после каждого нажатия стрелки вам надо будет жать на Enter!! Я не говорю, что мне надо писать игрушку, но и консольные программы иногда требуют управление клавишами.
Записан
RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #4 : 20-09-2006 17:16 » new

andrystepa, "ожидание ENTER" - это режим редактирования терминала. Его можно отключить. См. pinfo libc, раздел Low-Level Terminal Interface/Terminal Modes. Особенно почитай там Noncanonical Input.
« Последнее редактирование: 20-09-2006 17:20 от RXL » Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
andrystepa
Помогающий

ru
Offline Offline

« Ответ #5 : 20-09-2006 18:04 » 

andrystepa, "ожидание ENTER" - это режим редактирования терминала. Его можно отключить. См. pinfo libc, раздел Low-Level Terminal Interface/Terminal Modes. Особенно почитай там Noncanonical Input.
Все, спасибо! Прочитал, разобрался! Надо было установить атрибуты терминала на считывание с клавиатуры только одного символа. После этого функция getc() считывает один символ и завершается. Кому интересно, могу поподробнее.
Записан
RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #6 : 20-09-2006 18:17 » 

andrystepa, расскажи Улыбаюсь
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
andrystepa
Помогающий

ru
Offline Offline

« Ответ #7 : 24-09-2006 18:19 » 

В Unix Programming FAQ (v1.37), который находится - http://www.opennet.ru/docs/FAQ/programming/unix-programming.html есть полный ответ на мой вопрос, правда на английском языке. Вкратце: Терминалы обычно установлены в каноническую моду, когда ввод читается построчно, когда вводимая строка отредактирована и нажат Enter. Можно переключить терминал в неканоническую моду, за это отвечают функции, объявленные в заголовочном файле termios.h. С помощью них можно установить размер буфера, при заполнении которого происходит передача введенных символов в программу.
Пример создания функций переключения терминала:
Код:
 #include <stdlib.h>
     #include <stdio.h>
     
     #include <termios.h>
     #include <string.h>
     
     static struct termios stored_settings;
     
     void set_keypress(void)
     {
         struct termios new_settings;
     
         tcgetattr(0,&stored_settings);
     
         new_settings = stored_settings;
     
         /* Disable canonical mode, and set buffer size to 1 byte */
         new_settings.c_lflag &= (~ICANON);
         new_settings.c_cc[VTIME] = 0;
         new_settings.c_cc[VMIN] = 1;
     
         tcsetattr(0,TCSANOW,&new_settings);
         return;
     }
     
     void reset_keypress(void)
     {
         tcsetattr(0,TCSANOW,&stored_settings);
         return;
     }

Описание использованных функций и структур можно прочитать здесь: http://www.opennet.ru/man.shtml?topic=tcgetattr&category=3&russian=0

Записан
brood
Гость
« Ответ #8 : 02-05-2007 07:37 » 

в curses.h и ncurses.h есть функция getch()

----list.cpp----
Код:
#include <stdio.h>
#include <curses.h>
void main()
{
int c;
initscr();
cbreak();
noecho();
 do{
   c=getch();
   printw("%c",c);
 }
 while(c!=10);
endwin();
return 0;
}

---Makefile---
Код:
OBJ=list.o
CMPL=g++
list:$(OBJ)
       $(CMPL) -m486 -o list list.o -lncurses

list.o:list.cpp
       $(CMPL) -c list.cpp

Записан
McZim
Команда клуба

ru
Offline Offline
Пол: Мужской
Я странный


WWW
« Ответ #9 : 08-10-2008 13:14 » 

Лучше поздно чем никогда Улыбаюсь

нашел ошибку у предыдущего оратора:

Код:
void main()
{
...
...
...
return 0;
}

если уж функции void то ничего возвращать в конце не нужно, но лучше сделать int а не void.
Записан

The CBO without stats is like a morning without coffee. (c) T.Kyte.
McZim
Команда клуба

ru
Offline Offline
Пол: Мужской
Я странный


WWW
« Ответ #10 : 08-10-2008 13:19 » 

и Вот такой код не работает:

Код:
int main()
{
    int c;
    initscr();
    cbreak();
    noecho();

    do
    {
        c = getch();
        if(c == KEY_UP)
            printw("UP");
    }
    while(c != 10);

endwin();
return 0;
}

Кто может подсказать почему? Я туплю жестко.
Записан

The CBO without stats is like a morning without coffee. (c) T.Kyte.
Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #11 : 08-10-2008 14:41 » 

McZim, Что именно не работает, куда копать?
Записан

Не будите спашяго дракона.
             Джаффар (Коша)
RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #12 : 08-10-2008 15:03 » 

McZim, в отладчике пройди по шагам.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
McZim
Команда клуба

ru
Offline Offline
Пол: Мужской
Я странный


WWW
« Ответ #13 : 09-10-2008 10:13 » 

вот что говорит gdb

Код:
(gdb) run
Starting program: /home/mczim/main/keycode/bin/Debug/keycode

Breakpoint 1, main () at /home/mczim/main/keycode/main.cpp:29
29          initscr();
(gdb) step
30          cbreak();
(gdb) step
31          noecho();
(gdb) step
35              c = getch();
(gdb) step
36              if(c == KEY_UP)
(gdb) [A
(gdb) step
33          do
(gdb) step
35              c = getch();
(gdb) step
36              if(c == KEY_UP)

т.е. KEY_UP не приходит, а приходит  [A
Записан

The CBO without stats is like a morning without coffee. (c) T.Kyte.
McZim
Команда клуба

ru
Offline Offline
Пол: Мужской
Я странный


WWW
« Ответ #14 : 09-10-2008 13:16 » 

Разобрался.

Код:
#include <curses.h>

int main()
{
        int ch;

initscr();
raw();
keypad(stdscr, TRUE);
noecho();

    printw("Type any character to see it in bold\n");
    ch = getch();

    if(ch == KEY_F(1))
printw("F1 Key pressed");

    if(ch == KEY_UP)
        printw("UP Key pressed");

    if(ch == KEY_DOWN)
        printw("DOWN Key pressed");

    refresh();
    getch();
    endwin();

     return 0;
}
Записан

The CBO without stats is like a morning without coffee. (c) T.Kyte.
McZim
Команда клуба

ru
Offline Offline
Пол: Мужской
Я странный


WWW
« Ответ #15 : 09-10-2008 13:28 » 

А теперь внимание вопрос Улыбаюсь Возможно ли в инициализированном терминале curses работать с OCCI ведь когда устанавливаешь соединение с oracle, там насколько я понял подгружается своя оболочка.
Записан

The CBO without stats is like a morning without coffee. (c) T.Kyte.
RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #16 : 09-10-2008 19:36 » 

Погоди, OCI разве работает с терминалом? Это не API базы?
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
McZim
Команда клуба

ru
Offline Offline
Пол: Мужской
Я странный


WWW
« Ответ #17 : 10-10-2008 06:16 » 

Oracle C++ Call Interface (OCCI) я его юзаю. Я не уверен на счет консоли конечно, просто это мое предположение, так как когда устанавливаешь коннект с базой, то например стрелки вверх, вниз, влево, вправо, выдают закорючки, так же как если подключится к базе с помощью sqlplus, вот и сделал такое предположение.
Записан

The CBO without stats is like a morning without coffee. (c) T.Kyte.
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines