8

Phobos を使用して D2 で単一のキーストロークを取得する簡単なクロスプラットフォームの方法はありますか?

たとえば、「続行するには任意のキーを押してください...」というプロンプトや、Brainfuck インタープリターなどです。

私が試したすべてのメソッドでは、入力を渡す前に Enter キーを押す必要があります (たとえば、getchar())。

4

2 に答える 2

6

Windows 上の D2 で動作する最も簡単なソリューション:

import std.stdio : writefln;

extern(C) int kbhit();
extern(C) int getch();

void main()
{
    while(!kbhit())
    {
        // keep polling
        // might use Thread.Sleep here to avoid taxing the cpu.
    }

    writefln("Key hit was %s.", cast(char)getch());
}

D1 でも動作する可能性がありますが、試したことはありません。

以下は、 Walter の投稿を変更した Linux バージョンです。

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

extern(C) void cfmakeraw(termios *termios_p);

void main() 
{
    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
    writefln("The key hit is %s", cast(char)fgetc(stdin));

       // Close
    tcsetattr(1, TCSADRAIN, &ostate);       // return to original mode
}
于 2011-03-21T21:40:39.820 に答える
5

私はこの問題についていくつかの調査を行いましたが、D 1.0のPhobosライブラリには必要なものが正確に含まれていましたが、std.c.stdio.getch()D2.0にはこの機能がありません。Phobosの他の標準入力関数はどれもあなたが望む振る舞いをしていないようです。

私が理解しているように、これは、目的の動作(つまり、Enterキーを押す必要なしに単一の文字を取得する)がかなり非標準であり、比較的醜いプラットフォーム固有の方法で実装する必要があるためです。(初期の形式では、関数getchはCに存在していました<conio.h>。これは、標準Cライブラリの一部ではないにもかかわらず、事実上のクロスプラットフォーム標準になっているDOS固有のヘッダーです。)明らかに、Phobosランタイムライブラリのメンテナは次のことを決定しました。よりクリーンなライブラリの名前で、この特定の下位互換性のある機能を取り除きますが、この機能を犠牲にします。

手動宣言

伝えられるところによると、これをソースファイルに追加することで、この欠落している関数宣言を回避できます。

extern (C) int getch();

ただし、これによりリンカーエラーが発生することがわかりました。これは、関数が単に宣言をから削除するのではなく、ランタイムライブラリから完全に削除されたことを示していますstd.c.stdio。それは確かに試してみる価値があります—それはあなたのシステムとコンパイラでたまたま動作するかもしれません、私は本当に知りません。

編集2:これは実際にはWindowsで動作するようです。Linux側では失敗しました。WindowsでのDMDは、最初にPhobos / Dランタイム(phobos.lib)にリンクし、次にCランタイム(snn.lib)にリンクしているようです。ただし、Linuxでは、DMDは両方の部分を提供する1つのランタイムライブラリにリンクします。この違いにより、宣言されていない関数(それらの間)へのリンクがgetchWindowsでのみ機能するように見えます。関心のあるプラットフォームがWindowsだけの場合は、このソリューションがおそらく適しています。より多くのクロスプラットフォーム互換性が必要な場合は、読み進めてください。

ncurses

もう1つの可能性は、ncursesライブラリを使用することです。getchライブラリのDバインディングを見つけるか、Cインターフェイスを使用するだけでかっこいい場合は、必要なことを確実に実行する関数を実装します。必要な関数を呼び出すだけでなく、わずかなセットアップが必要になることに注意してください。このスレッドには、この問題に関する詳細情報があります。

D 1.0

さて、いくつかのかなり醜い解決策のために。D 1.0を使用すると、Phobos標準ライブラリで必要なものを見つけることができますが、これには明らかに古い、より無愛想なバージョンの言語を使用する必要があり、私は個人的に、標準ライブラリに1つのコンソールIO関数がないことを正当化できるとは思いません。古いバージョンのDを使用するため。

タンゴもD2.0への切り替えgetchで宣言(下tango.stdc.stdio)を失ったと思いますが、タンゴについての知識は非常に限られているので、間違っているかもしれません。

自分で書く

あなたが決心しているなら、あなたはただあなた自身を書くことができますgetchGoogleコード検索getchを使用したクロスプラットフォームのC実装を見つけることができなかったため、Dに単純に適応できる比較的単純な10行程度の関数実装の可能性について悲観的になりました。

一方、D言語を設計したWalter Brightは、この種の関数のD実装をここで提供します。cfmakerawただし、 DMD2コンパイラの現在のバージョンでは、シンボルの1つである、が未定義であるため、これでも多少古くなっているように見えます。ただし、これは実行可能なソリューションに非常に近いものです。

于 2011-03-21T21:31:35.547 に答える