3

我读了这篇文章并尝试用 D 编程语言做练习,但在第一个练习中遇到了问题。

(1) 在无限循环中显示一系列数字(1,2,3,4,5....等)。如果有人按下特定键(比如 ESCAPE 键),程序应该退出。

当然无限循环不是什么大问题,但其余的都是。我怎样才能在 D/Tango 中抓住一个关键点?在探戈常见问题解答中,它说使用 C 函数 kbhit() 或 get(),但据我所知,这些不在 C 标准库中,也不存在于我用来编程的 Linux 机器附带的 glibc 中。

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

我怎么能做到?

4

5 回答 5

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
于 2008-11-04T11:30:58.317 回答
2

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

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

于 2008-09-19T06:34:12.873 回答
0

Thanks for both of your replies.

Unfortunately, my main development environment is Linux + GDC + Tango, so I don't have conio.h, since I don't use DMC as my C compiler.

And I also found both getc() and getchar() is also line buffered in my development environment, so it could not achieve what I wish I could do.

In the end, I've done this exercise by using GNU ncurses library. Since D could interface C library directly, so it does not take much effort. I just declare the function prototype that I used in my program, call these function and linking my program against ncurses library directly.

It works perfectly on my Linux machine, but I still not figure out how could I do this without any 3rd party library and could run on both Linux and Windows yet.

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;
}
于 2008-09-19T08:02:51.990 回答
0

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

如果 tango 没有所需的功能,生成绑定很容易。(看看 CPP 以消除任何宏观垃圾。)

于 2008-09-19T04:15:56.917 回答
0

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

于 2009-04-01T13:43:54.533 回答