Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/72.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/iphone/36.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在C中向管道写入字符_C_Char_Signals_Fork_Pipe - Fatal编程技术网

在C中向管道写入字符

在C中向管道写入字符,c,char,signals,fork,pipe,C,Char,Signals,Fork,Pipe,我有下面的程序,它基本上是从键盘读取字符(getch()不需要单击“回车”即可完成此操作,函数取自此处:) ,然后,如果char是合法移动之一(左、右等),它将其写入管道,draw.out将从中读取 draw.out读取接收到的输入并打印到屏幕上。(假设这个程序工作正常,我保证问题只出现在下面的代码中) 问题是: draw.out的行为就像它一次又一次地接收我的输入一样。这意味着,出于某种原因,即使我只按了一次exmaple的DOWN键,它仍会发送draw.out,就像我多次单击它一样 在发送一

我有下面的程序,它基本上是从键盘读取字符(getch()不需要单击“回车”即可完成此操作,函数取自此处:) ,然后,如果char是合法移动之一(左、右等),它将其写入管道,draw.out将从中读取

draw.out读取接收到的输入并打印到屏幕上。(假设这个程序工作正常,我保证问题只出现在下面的代码中)

问题是:

  • draw.out的行为就像它一次又一次地接收我的输入一样。这意味着,出于某种原因,即使我只按了一次exmaple的DOWN键,它仍会发送draw.out,就像我多次单击它一样

  • 在发送一个输入后,我不能再发送了,就好像循环停止了一样

  • 好几个小时来我都在想这个。。。我非常感谢你的帮助

    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);
    }
    
    int main(int argc,const char*argv[]
    {
    pid_t child_pid;
    国际食品和药物管理局[2];
    
    如果(管道(fda)在发送字符
    c
    后,需要将其设置为除
    旋转
    以外的值

    如果您不
    getch()
    将永远不会被第二次调用

    因此,在外部
    while
    (就在
    kill
    之后)或循环开始时(就在
    while
    包含
    getch()
    调用之前),添加如下内容

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

    将while循环更改为do/while循环,以确保始终至少调用一次getch()

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

    哦,天哪!非常感谢!6个小时了,头疼得厉害!我感到很轻松。谢谢