C++;管道问题 我试图把我的C++程序分叉,并把父输出直接输入到孩子的输入中,我使用的是PIPER()和Frk()。在程序的目录中有一个名为input.txt的文件。不幸的是,我得到的唯一输出是“wc:stdin:read:Bad file descriptor”。有人知道这是为什么吗?如果是,我做错了什么?谢谢 #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; } #包括 #包括 #包括 #包括 #包括 #包括 #包括 #包括 #包括 #包括 #包括 int main(int argc,char*argv[]){ int管道[2]、pid、标准输入、标准输出; stdIn=dup(0); stdOut=dup(1); 管道; pid=fork(); 如果(pid==0){ dup2(管道[1],0); 关闭(管道[1]); execlp(“wc”,“wc”,NULL); } 否则{ dup2(管道[0],1); 关闭(管道[0]); std::cout

C++;管道问题 我试图把我的C++程序分叉,并把父输出直接输入到孩子的输入中,我使用的是PIPER()和Frk()。在程序的目录中有一个名为input.txt的文件。不幸的是,我得到的唯一输出是“wc:stdin:read:Bad file descriptor”。有人知道这是为什么吗?如果是,我做错了什么?谢谢 #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; } #包括 #包括 #包括 #包括 #包括 #包括 #包括 #包括 #包括 #包括 #包括 int main(int argc,char*argv[]){ int管道[2]、pid、标准输入、标准输出; stdIn=dup(0); stdOut=dup(1); 管道; pid=fork(); 如果(pid==0){ dup2(管道[1],0); 关闭(管道[1]); execlp(“wc”,“wc”,NULL); } 否则{ dup2(管道[0],1); 关闭(管道[0]); std::cout,c++,pipe,fork,C++,Pipe,Fork,管道向后,管道的写入端已连接到wc的标准输入。在wc检测到文件结束情况并正常终止之前,需要在两个进程中关闭管道的写入端 您还错误地将原始标准输出恢复为父对象的标准输入 此外,默认情况下,wc不会将标准输入解释为列表文件名,因此不会读取input.txt程序中有几个问题需要解决: 使用STDIN_FILENO和STDOUT_FILENO而不是0和1。此值可能在不同的平台上发生变化,并且您还犯了一个错误,如果您使用名称而不是值,则可以避免此错误,例如dup2(STDOUT,0)复制了stdin,您

管道向后,管道的写入端已连接到
wc
的标准输入。在
wc
检测到文件结束情况并正常终止之前,需要在两个进程中关闭管道的写入端

您还错误地将原始标准输出恢复为父对象的标准输入


此外,默认情况下,
wc
不会将标准输入解释为列表文件名,因此不会读取
input.txt

程序中有几个问题需要解决:

  • 使用
    STDIN_FILENO
    STDOUT_FILENO
    而不是0和1。此值可能在不同的平台上发生变化,并且您还犯了一个错误,如果您使用名称而不是值,则可以避免此错误,例如
    dup2(STDOUT,0)
    复制了
    stdin
    ,您需要在此处复制
    stdout
  • 您应该在子管道和父管道中关闭管道的写入端
  • 通过从
    stdin
    读取
    wc
    ,您将向其传递“input.txt”字符串-它将返回该字符串的统计信息,而不是文件的统计信息。您可以通过打开该文件的文件描述符或使用
    exec*
    cat
    来修复它
  • 调用
    pipe()
    execlp()
    之类的函数都不会检查失败。您应该这样做:

    if (pipe(pipes) == -1) {
        perror("pipe");
        exit(1);
    }
    
  • 您不需要
    stdIn
    变量

  • 您将在下面找到固定代码(但它没有实现我在(5)中描述的内容):


    关于
    wc
    不处理标准输入,@mathJohn可以调用
    xargs-wc
    #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;
    }
    
    execlp("xargs", "xargs","wc",NULL);