如何在D Programming Language + Tango中获取单键击中?

时间:2008-09-19 04:08:07

标签: input d tango

我读了article并尝试用D编程语言练习,但在第一次练习中遇到问题。

  

(1)显示一系列数字   (1,2,3,4,5 ......等)无限   环。如果,该程序应该退出   有人点击特定的密钥(说   ESCAPE密钥)。

当然无限循环不是一个大问题,但剩下的就是。我怎么能在D / Tango中获得一个关键击中?在tango FAQ中它说使用C函数kbhit()或get(),但据我所知,这些不在C标准库中,并且不存在于我用于编程的Linux机器附带的glibc中。

我知道我可以使用像ncurses这样的第三方库,但它有同样的问题,就像kbhit()或get()一样,它不是C或D中的标准库而且没有预先安装在Windows上。我希望我能完成这个练习只使用D / Tango并且可以在Linux和Windows机器上运行它。

我怎么能这样做?

5 个答案:

答案 0 :(得分:6)

以下是使用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

答案 1 :(得分:2)

kbhit确实不是任何标准C接口的一部分,但可以在conio.h中找到。

但是,您应该能够使用tango.stdc.stdio中的getc / getchar - 我更改了您提到的常见问题以反映这一点。

答案 2 :(得分:0)

D通常具有所有可用的C stdlib(Tango或Phobos),因此对于GNU C的这个问题的答案也应该在D中工作。

如果探戈没有所需的功能,生成绑定很容易。 (看看CPP来切断任何宏观垃圾。)

答案 3 :(得分:0)

感谢您的回复。

不幸的是,我的主要开发环境是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;
}

答案 4 :(得分:0)

正如Lars所指出的,你可以使用conio.h中定义的_kbhit和_getch,并在(我相信)msvcrt for Windows中实现。这是一个article with C++ code for using _kbhit and _getch