1

私は基本的にキーボードから文字を読み取る次のプログラムを持っています(getch()は「ENTER」をクリックする必要なしにこれを行います、関数はここから取られます:Enterが押されるのを待たずに標準入力から文字をキャプチャします)、そしてもしchar は正当な移動 (LEFT、RIGHT など) の 1 つであり、draw.out が読み取っているパイプに書き込みます。

draw.out は、受信した入力を読み取り、画面に出力しています。(このプログラムが正常に動作すると仮定します。問題は次のコードのみにあると確信しています)。

問題はそれです:

  1. draw.out は、私の入力を何度も受け取っているように動作しています。つまり、どういうわけか、たとえば DOWN キーを 1 回だけ押したのに、何度もクリックしたかのように draw.out が送信されます。

  2. 1 つの入力を送信した後、ループが停止しているかのように送信できなくなります。

これについて何時間も頭を悩ませようとしました...助けていただければ幸いです。

int main(int argc, const char* argv[])
{
pid_t child_pid;
int fda[2];
if(pipe(fda)<0)
    perror("pipe error");

if((child_pid=fork())<0)
    perror("fork error");
else
{
    //if we're in father
    if(child_pid>0)
    {
        char c=' ';

        //close read side
        close(fda[0]);

        while(c!=QUIT)
        {
            //get an instruction from keyboard
            while(c!=ROTATE && c!=LEFT && c!=RIGHT &&
                    c!=DOWN && c!=QUIT)
            {
                c=getch();
            }

            //write the instruction to pipe
            write(fda[1],&c,1);
            //notify the child
            kill(child_pid,SIGUSR2);

        }
    }
    //if we're in child process
    else
    {
        dup2(fda[0],0);
        close(fda[0]);
        close(fda[1]);
        execl("./draw.out","./draw.out",NULL);
    }
}

//close everything
close(fda[0]);
close(fda[1]);
return 0;
}

//this function works well in linux with tsch installed or in SSH bash shell
char getch()
{
char buf = 0;
struct termios old = {0};
if (tcgetattr(0, &old) < 0)
        perror("tcsetattr()");
old.c_lflag &= ~ICANON;
old.c_lflag &= ~ECHO;
old.c_cc[VMIN] = 1;
old.c_cc[VTIME] = 0;
if (tcsetattr(0, TCSANOW, &old) < 0)
        perror("tcsetattr ICANON");
if (read(0, &buf, 1) < 0)
        perror ("read()");
old.c_lflag |= ICANON;
old.c_lflag |= ECHO;
if (tcsetattr(0, TCSADRAIN, &old) < 0)
        perror ("tcsetattr ~ICANON");
return (buf);
}
4

2 に答える 2

1

char を送信したら、 、、またはc以外の値に設定する必要があります。ROTATELEFTRIGHTDOWN

そうしないgetch()と二度と呼ばれない…

したがって、アウターの終わりwhile( の直後) またはループの開始時 (呼び出しを含む のkill直前) に次のようなものを追加します。whilegetch()

if (c != QUIT)
  c = ' ';
于 2013-04-20T15:03:56.267 に答える