C ++管道问题 [英] C++ piping issue

查看:175
本文介绍了C ++管道问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图fork我的c ++程序,并将父输出到childs输入,我使用pipe()和fork()。在程序的目录中有一个名为input.txt的文件。不幸的是,我得到的唯一输出是wc:stdin:read:Bad file descriptor。有人知道为什么是这样吗?如果是这样我做错了什么?感谢

I am trying to to fork my c++ program and direct the parents output into the childs input, I am using pipe() and fork(). In the directory of the program there is a file called input.txt. Unfortunately the only output I get is "wc: stdin: read: Bad file descriptor". Does anyone know why this is? If so what am I doing wrong? Thanks

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <errno.h>
#include <string.h>
#include <iostream>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<stdio.h>

int main(int argc, char *argv[]){

        int pipes[2],pid,stdIn,stdOut;

        stdIn = dup(0);
        stdOut = dup(1);

        pipe(pipes);

        pid = fork();

        if(pid == 0){
                dup2(pipes[1],0);
                close(pipes[1]);
                execlp("wc","wc",NULL);
        }
        else{
                dup2(pipes[0],1);
                close(pipes[0]);
                std::cout<<"input.txt"<<std::endl;
                dup2(stdOut,0);
                std::cout<<"parent done\n";
                wait(NULL);
        }

        std::cout<<"after"<<std::endl;
        return 0;
 }


推荐答案

在您的程序中固定:


  1. 使用 STDIN_FILENO STDOUT_FILENO 而不是0和1.这个值可能会在不同的平台上更改,你也犯了一个错误,如果你使用名称而不是值,可能可以避免,例如 dup2(stdOut,0); 重复 stdin ,您需要复制 stdout stdin 中读取 wc ,然后将input.txt字符串传递给它 - 它将返回stats那个字符串,不是为文件。你可以修复它为该文件打开一个文件描述符,或者使用 exec c>与 cat

  2. 您没有调用 pipe() execlp()检查故障。你应该这样做:

  1. Use STDIN_FILENO and STDOUT_FILENO instead of 0 and 1. This values may change on different platforms and you have also made a mistake which could probably be avoided if you've used names instead of value, e.g. dup2(stdOut,0); duplicated stdin and you need to duplicate stdout here.
  2. You should close write end of the pipe in both child and parent.
  3. By making wc read from stdin, you are then passing "input.txt" string to it - it will return stats for that string, not for the file. You could either fix it be opening a file descriptor for that file or using exec* with cat.
  4. None of your calls the functions like pipe() or execlp() checks for failure. You should do it like that:

if (pipe(pipes) == -1) {
    perror("pipe");
    exit(1);
}


  • 您不需要 stdIn 变量。

    您将在下面找到固定代码(5)中描述的):

    You will find fixed code below (it does not implement what I've described in the (5) though):

    #include <stdio.h>
    #include <unistd.h>
    #include <stdlib.h>
    #include <sys/wait.h>
    #include <errno.h>
    #include <string.h>
    #include <iostream>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <stdio.h>
    
    int main(int argc, char *argv[]) {
        int pipes[2], pid, stdOut;
    
        stdOut = dup(STDOUT_FILENO);
    
        pipe(pipes);
    
        pid = fork();
    
        if (pid == 0) {
            dup2(pipes[0], STDIN_FILENO);
            /* You need to close write end of the pipe here */
            close(pipes[1]);
            execlp("wc", "wc", NULL);
        } else {
            std::cout << "Parent setup" << std::endl;
            dup2(pipes[1], STDOUT_FILENO);
            /* You need to close write end of the pipe here as well */
            close(pipes[1]); 
            /* This will only send the string "input.txt" through the pipe, to the
             * wc command */
            std::cout << "input.txt" << std::endl;
            dup2(stdOut, STDOUT_FILENO);
            std::cout << "Parent done" << std::endl;
            wait(NULL);
        }
    
        std::cout << "Program finished" << std::endl;
        return 0;
    }
    

    EDIT:其他答案,你可以简单地使用 xargs wc 来读取stdint作为文件参数:

    As suggested in the comment to the other answer, you could simple use xargs wc to read stdint as file argument:

    execlp("xargs", "xargs","wc",NULL);
    

    这篇关于C ++管道问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

  • 查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆