如何在 D 编程语言 + Tango 中获取单键命中?

How can I grab single key hit in D Programming Language + Tango?

提问人:Brian Hsu 提问时间:9/19/2008 最后编辑:he_the_greatBrian Hsu 更新时间:4/13/2023 访问量:1546

问:

我读了这篇文章,并尝试用 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 机器上运行它。

我该怎么做?

输入 D 探戈

评论


答:

0赞 BCS 9/19/2008 #1

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

如果 tango 没有所需的功能,则生成绑定很容易。(看看CPP来减少任何宏观垃圾。

2赞 larsivi 9/19/2008 #2

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

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

0赞 Brian Hsu 9/19/2008 #3

感谢您的回复。

不幸的是,我的主要开发环境是 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;
}
6赞 Walter Bright 11/4/2008 #4

下面是您在 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
0赞 DK. 4/1/2009 #5

正如 Lars 所指出的,您可以使用 conio.h 中定义的_kbhit和_getch,并在(我相信)适用于 Windows 的 msvcrt 中实现。这是一篇包含使用 _kbhit 和 _getch 的C++代码的文章