I read this article and try to do the exercise in D Programming Language, but encounter a problem in the first exercise.
我读了这篇文章并试着用D编程语言练习,但在第一次练习中遇到了问题。
(1) Display series of numbers (1,2,3,4, 5....etc) in an infinite loop. The program should quit if someone hits a specific key (Say ESCAPE key).
(1)在无限循环中显示数字序列(1,2,3,4,5 ......等)。如果有人按特定键(Say ESCAPE键),程序应该退出。
Of course the infinite loop is not a big problem, but the rest is. How could I grab a key hit in D/Tango? In tango FAQ it says use C function kbhit() or get(), but as I know, these are not in C standard library, and does not exist in glibc which come with my Linux machine which I use to programming.
当然,无限循环不是一个大问题,但其余的是。我如何才能在D / Tango中获得重点?在tango FAQ中它说使用C函数kbhit()或get(),但据我所知,这些不在C标准库中,并且不存在于我用于编程的Linux机器中的glibc中。
I know I can use some 3rd party library like ncurses, but it has same problem just like kbhit() or get(), it is not standard library in C or D and not pre-installed on Windows. What I hope is that I could done this exercise use just D/Tango and could run it on both Linux and Windows machine.
我知道我可以使用像ncurses这样的第三方库,但它有像kbhit()或get()一样的问题,它不是C或D中的标准库,也没有预装在Windows上。我希望我能完成这个练习只使用D / Tango,并且可以在Linux和Windows机器上运行它。
How could I do it?
我怎么能这样做?
5 个解决方案
#1
6
Here's how you do it in the D programming language:
以下是您使用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
2
kbhit is indeed not part of any standard C interfaces, but can be found in conio.h.
kbhit确实不是任何标准C接口的一部分,但可以在conio.h中找到。
However, you should be able to use getc/getchar from tango.stdc.stdio - I changed the FAQ you mention to reflect this.
但是,您应该能够使用tango.stdc.stdio中的getc / getchar - 我更改了您提到的常见问题以反映这一点。
#3
0
D generally has all the C stdlib available (Tango or Phobos) so answers to this question for GNU C should work in D as well.
D通常具有所有可用的C stdlib(Tango或Phobos),因此对于GNU C的这个问题的答案也应该在D中工作。
If tango doesn't have the needed function, generating the bindings is easy. (Take a look at CPP to cut through any macro junk.)
如果探戈没有所需的功能,生成绑定很容易。 (看一看CPP来消除任何宏观垃圾。)
#4
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.
不幸的是,我的主要开发环境是Linux + GDC + Tango,所以我没有conio.h,因为我没有使用DMC作为我的C编译器。
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.
我还发现getc()和getchar()在我的开发环境中也是行缓冲的,所以它无法达到我希望的能力。
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.
最后,我使用GNU ncurses库完成了这个练习。由于D可以直接连接C库,因此不需要花费太多精力。我只是声明我在程序中使用的函数原型,调用这些函数并直接将我的程序与ncurses库链接。
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.
它在我的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;
}
#5
0
As Lars pointed out, you can use _kbhit and _getch defined in conio.h and implemented in (I believe) msvcrt for Windows. Here's an article with C++ code for using _kbhit and _getch.
正如Lars所指出的,你可以使用在conio.h中定义的_kbhit和_getch,并在(我相信)msvcrt for Windows中实现。这是一篇包含使用_kbhit和_getch的C ++代码的文章。
#1
6
Here's how you do it in the D programming language:
以下是您使用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
2
kbhit is indeed not part of any standard C interfaces, but can be found in conio.h.
kbhit确实不是任何标准C接口的一部分,但可以在conio.h中找到。
However, you should be able to use getc/getchar from tango.stdc.stdio - I changed the FAQ you mention to reflect this.
但是,您应该能够使用tango.stdc.stdio中的getc / getchar - 我更改了您提到的常见问题以反映这一点。
#3
0
D generally has all the C stdlib available (Tango or Phobos) so answers to this question for GNU C should work in D as well.
D通常具有所有可用的C stdlib(Tango或Phobos),因此对于GNU C的这个问题的答案也应该在D中工作。
If tango doesn't have the needed function, generating the bindings is easy. (Take a look at CPP to cut through any macro junk.)
如果探戈没有所需的功能,生成绑定很容易。 (看一看CPP来消除任何宏观垃圾。)
#4
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.
不幸的是,我的主要开发环境是Linux + GDC + Tango,所以我没有conio.h,因为我没有使用DMC作为我的C编译器。
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.
我还发现getc()和getchar()在我的开发环境中也是行缓冲的,所以它无法达到我希望的能力。
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.
最后,我使用GNU ncurses库完成了这个练习。由于D可以直接连接C库,因此不需要花费太多精力。我只是声明我在程序中使用的函数原型,调用这些函数并直接将我的程序与ncurses库链接。
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.
它在我的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;
}
#5
0
As Lars pointed out, you can use _kbhit and _getch defined in conio.h and implemented in (I believe) msvcrt for Windows. Here's an article with C++ code for using _kbhit and _getch.
正如Lars所指出的,你可以使用在conio.h中定义的_kbhit和_getch,并在(我相信)msvcrt for Windows中实现。这是一篇包含使用_kbhit和_getch的C ++代码的文章。