Skip to main content
 首页 » 编程设计

c之如何在不同程序之间使用管道

2026年05月17日20unruledboy

再次提问并修改代码...

我需要在 linux 中创建三个名为 program0 program1 和 program2 的程序。

程序 0:创建一个具有两个子进程的父进程并执行程序 1 和程序 2 及其子进程等待它们完成并关闭。

程序 1:从用户那里获取文件名并将文本写入文件。当按下 CTNL+D 并创建管道时完成写入。之后使用 cat 命令将文件写入标准输出并使用 dup() 创建里面有文件的管道。

程序2:借助dup()从管道中读取文件名,然后执行wc命令。

到目前为止,我设法创建了所有程序,并且没有出现编译错误。程序 0 执行这两个程序。程序 1 也在工作并将文件发送到管道,但程序 2 无法从管道读取它,它打印出奇怪的符号..

当我尝试从 program1 中的管道读取时,它可以工作(请参阅 program1 中停用的代码),但如果我将它放在 program2 中,则相同的代码不起作用。

那么在我将尝试在 program2 中执行 wc 命令之后,我怎样才能使 program2 从管道读取,但首先我应该能够看到它从 stdout 获取文件输入,所以如何?

我知道它有点长,但请大家帮帮我......

程序 0

#include <stdio.h> 
#include <sys/types.h> 
#include <sys/wait.h> 
#include <unistd.h> 
#include <stdlib.h> 
#define MAX 999 
 
int main() 
{ 
pid_t pid1, pid2; 
 
pid1 = fork(); 
if(pid1<0)  
{ 
fprintf(stderr,"Fork basarisiz"); 
exit(-1); 
} 
else if (pid1 ==0)/*child prosesleri*/ 
{ 
 
 
printf("program1\n"); 
 
execlp("./program1","program1",NULL); 
execlp("./program2","program2",NULL); 
} 
else /*parent procsesleri */ 
{ 
wait(NULL); 
pid2 = fork(); 
if(pid2<0)  
{ 
fprintf(stderr,"Fork basarisiz"); 
exit(-1); 
} 
else if (pid2 ==0)/*child prosesleri*/ 
{ 
printf("\n"); 
printf("Program 2\n"); 
printf("\n"); 
execlp("./program2","program2",NULL); 
//printf("\n"); 
} 
else 
{ 
} 
 
///////////////////////////////////////////////////////////////////////// 
wait(NULL); 
printf("\n"); 
printf("Parent:Two child processes have successfully been created\n"); 
printf("Parent:Two child processes have successfully been terminated\n"); 
printf("Parent:This process will now terminate\n"); 
printf("\n"); 
exit(0); 
} 
} 

程序一

#include <stdio.h>  
#include <stdlib.h>  
#include <string.h> 
#include <sys/types.h> 
#include <unistd.h> 
#define MAX 999 
 
int main()  
{  
    char c[10000];               
    char file[10000]; 
    int words; 
    printf("Child1:A text file will be created\n"); 
    printf("Child1:Enter the name of the file\n"); 
    scanf("%123s",file); 
    strcat(file,".txt");  
    FILE * pf;  
    pf = fopen(file, "w" ); 
 
   if (!pf) 
   fprintf( stderr, "I couldn't open the file.\n" ); 
 
   else 
   { 
        printf("Child1: Input a number of text lines ended, each ended by a CR (carriage return).\n"); 
 
 
///////////////////////////// 
 
  do 
{ 
  if (NULL != fgets(c, sizeof(c), stdin)) 
  { 
    if (0 == strcmp(c, ".\n"))  
    { 
      break; 
    } 
 
    fprintf(pf, "%s", c); 
  } 
  else 
  { 
    if (0 != ferror(stdin)) 
    { 
      fprintf(stderr, "An error occured while reading from stdin\n"); 
    } 
    else 
    { 
      printf("Child1: Finish the input by CNTL^D\n"); 
    } 
 
    break; 
  } 
} while (1); 
 
///////////////////////////// 
 
    } 
    printf("\nChild1:The file %s is succesfully created and saved in the current dictionary\n",file); 
 
 
////////////////////////////////////////////// 
 
 
 
/////////////////////////pipe/////////////// 
 
    fclose(pf);  // close file   
 
        char ch; 
        int outcount = 0; 
        int     fd[2], nbytes; 
        pid_t   childpid; 
int i; 
        char f2[2]; 
 
        char    readbuffer[80]; 
 
        pipe(fd); 
 
        if((childpid = fork()) == -1) 
        { 
                perror("fork"); 
                exit(1); 
        } 
 
        if(childpid == 0) 
 
        {       printf("\nChild1:The file written to pipe with cat\n"); 
                close(1) ; 
                dup(fd[1]); 
                close(fd[0]); 
                execlp("/bin/cat", "cat", file,NULL); 
 
        } 
        else 
        { 
            wait(NULL);   
            //close(0) ;  
            //dup(fd[0]) ; 
            //close(fd[1]); 
            //nbytes = read(fd[0], readbuffer, sizeof(readbuffer)); 
 
            //printf("%s\n",readbuffer); 
        } 
 
        return(0); 
}  

程序 2

#include <stdio.h>  
#include <stdlib.h>  
#include <string.h> 
#include <sys/types.h> 
#include <unistd.h> 
 
int main()  
{  
        int   fd[2],nbytes; 
        pid_t   childpid; 
        char    readbuffer[80]; 
 
        pipe(fd); 
 
        if((childpid = fork()) == -1) 
        { 
                perror("fork"); 
                exit(1); 
        } 
 
        if(childpid == 0) 
        { 
        } 
        else 
        { 
            close(0) ;  
            dup(fd[0]) ; 
            close(fd[1]); 
            nbytes = read(fd[0], readbuffer, sizeof(readbuffer)); 
            printf("%s\n",readbuffer); 
 
        } 
 
        return(0); 
} 

请您参考如下方法:

您可能需要查看 execve(2)(用于启动 cat)和 dup2(2)(用于覆盖stdinstdout 根据需要)。 execve 将用不同的程序(相同的 PID,相同的文件描述符)覆盖当前正在执行的程序,而 dup2 将允许您重新定义任何标准文件描述符以指向进入您提供给它的任何文件描述符(例如管道的任何末端)。