Как я могу получить одно нажатие клавиши в D Programming Language + Tango? - PullRequest
3 голосов
/ 19 сентября 2008

Я прочитал эту статью и попытался выполнить упражнение на языке программирования D, но столкнулся с проблемой в первом упражнении.

(1) Показать ряд чисел (1,2,3,4, 5 .... и т. Д.) В бесконечном петля. Программа должна выйти, если кто-то нажимает конкретный ключ (скажем, Ключ ESCAPE).

Конечно, бесконечный цикл не большая проблема, но остальное есть. Как я могу получить ключевой удар в D / Tango? В FAQ по танго говорится, что используйте функцию C kbhit () или get (), но, как я знаю, они не входят в стандартную библиотеку C и не существуют в glibc, поставляемой с моей машиной Linux, которую я использую для программирования.

Я знаю, что могу использовать какую-то стороннюю библиотеку, такую ​​как ncurses , но она имеет ту же проблему, что и kbhit () или get (), это не стандартная библиотека на C или D и не предустановленная на винде. Я надеюсь, что смогу выполнить это упражнение, используя только D / Tango, и смог запустить его как на Linux, так и на Windows.

Как я мог это сделать?

Ответы [ 5 ]

6 голосов
/ 04 ноября 2008

Вот как вы делаете это на языке программирования D:

    import std.c.stdio;
    import std.c.linux.termios;

    termios  ostate;                 /* saved tty state */
    termios  nstate;                 /* values for editor mode */

    // Open stdin in raw mode
    /* Adjust output channel        */
    tcgetattr(1, &ostate);                       /* save old state */
    tcgetattr(1, &nstate);                       /* get base of new state */
    cfmakeraw(&nstate);
    tcsetattr(1, TCSADRAIN, &nstate);      /* set mode */

   // Read characters in raw mode
    c = fgetc(stdin);

    // Close
    tcsetattr(1, TCSADRAIN, &ostate);       // return to original mode
2 голосов
/ 19 сентября 2008

kbhit действительно не является частью каких-либо стандартных интерфейсов C, но его можно найти в conio.h.

Однако вы должны иметь возможность использовать getc / getchar из tango.stdc.stdio - я изменил часто задаваемые вопросы, которые вы упоминаете, чтобы отразить это.

0 голосов
/ 01 апреля 2009

Как указал Ларс, вы можете использовать _kbhit и _getch, определенные в conio.h и реализованные в (я считаю) msvcrt для Windows. Вот статья с кодом C ++ для использования _kbhit и _getch .

0 голосов
/ 19 сентября 2008

Спасибо за оба ваших ответа.

К сожалению, моя основная среда разработки - Linux + GDC + Tango, поэтому у меня нет conio.h, так как я не использую DMC в качестве моего компилятора C.

И я также обнаружил, что и getc (), и getchar () также являются буферизованными в моей среде разработки, поэтому он не может достичь того, чего я хотел бы.

В конце концов, я выполнил это упражнение, используя библиотеку GNU ncurses. Поскольку D может напрямую взаимодействовать с библиотекой C, это не требует особых усилий. Я просто объявляю прототип функции, который использовал в своей программе, вызываю эти функции и напрямую связываю мою программу с библиотекой ncurses.

Он отлично работает на моей машине с Linux, но я до сих пор не понимаю, как я могу это сделать без какой-либо сторонней библиотеки и еще может работать как на Linux, так и на Windows.

import tango.io.Stdout;
import tango.core.Thread;

// Prototype for used ncurses library function.
extern(C)
{
    void * initscr();
    int cbreak ();
    int getch();
    int endwin();
    int noecho();
}

// A keyboard handler to quit the program when user hit ESC key.
void keyboardHandler ()
{
    initscr();
    cbreak();
    noecho();
    while (getch() != 27) {
    }
    endwin();
}

// Main Program
void main ()
{
    Thread handler = new Thread (&keyboardHandler);
    handler.start();

    for (int i = 0; ; i++) {
        Stdout.format ("{}\r\n", i).flush;

        // If keyboardHandler is not ruuning, it means user hits
        // ESC key, so we break the infinite loop.
        if (handler.isRunning == false) {
            break;
        }
    }

    return 0;
}
0 голосов
/ 19 сентября 2008

D, как правило, имеет все доступные C-stdlib (Танго или Фобос), поэтому ответы на этот вопрос для GNU C также должны работать в D

Если у танго нет нужной функции, генерировать привязки легко. (Взгляните на CPP, чтобы пробиться через любой макротред.)

...