2013-04-20 66 views
1

我有以下程序,它基本上是從鍵盤讀取字符(getch()這樣做,而不需要點擊'ENTER',功能取自:Capture characters from standard input without waiting for enter to be pressed) ,然後如果char是合法的動作之一(左,右等),它將它寫入管道,draw.out正在讀取。寫字符到管道C

draw.out正在讀取它接收到的輸入並打印到屏幕上。 (假設這個程序工作正常,我保證問題只在下面的代碼中)。

的問題是,認爲:

  1. draw.out行事像它一遍又一遍recieving我的輸入。這意味着,出於某種原因,即使我按下例如DOWN鍵只有一次,它會發送draw.out,就像我多次點擊它一樣。

  2. 發送一個輸入後,我無法再發送,就好像循環停止一樣。

試圖打破我的頭這個好幾個小時......我真的很感謝幫助。

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); 
} 

回答

1

您發送的字符後c您需要將其設置爲ROTATELEFTRIGHTDOWN以外的值。

如果不getch()將永遠不會被稱爲第二次......

在外 while(只是 kill後)結束

所以還是在循環的開始(僅僅包含while前在getch()調用)添加類似

if (c != QUIT) 
    c = ' '; 
+0

天啊!非常感謝你! 6個小時,很多頭疼!我感到如此輕鬆。謝謝 – Jjang 2013-04-20 15:10:49

+0

不客氣。這就是我們在這裏:D – fredrik 2013-04-20 15:21:25

1

更改while循環do/while循環迴路,以保證殘培()始終調用至少一次。

do 
{ 
    c = getch(); 
} 
while (c != ROTATE && c != LEFT && c != RIGHT && c != DOWN && c != QUIT);