C Linux管道:函数读取和写入中的文件描述符错误

C Linux管道:函数读取和写入中的文件描述符错误,c,linux,pipe,C,Linux,Pipe,我正在学习C中的管道,我的代码有一个问题: 我的程序在父进程和子进程之间创建子进程和管道。我试图通过管道将一个简单的字符串从父对象发送到子对象。但由于某些原因,我收到了函数读取和写入的错误消息: "read error: Bad file descriptor" "write error: bad file descriptor" 我不知道问题出在哪里,我刚刚开始学习C中的管道 这是我的密码: #include <stdio.h> #incl

我正在学习C中的管道,我的代码有一个问题:

我的程序在父进程和子进程之间创建子进程和管道。我试图通过管道将一个简单的字符串从父对象发送到子对象。但由于某些原因,我收到了函数读取写入的错误消息:

"read error: Bad file descriptor"
"write error: bad file descriptor"
我不知道问题出在哪里,我刚刚开始学习C中的管道

这是我的密码:

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>

int err( const char* what )//function that writes errors
{
    perror( what );
    exit( -1 );
}

int main()
{
    int fdes[2]; //File descriptors for pipe
    pid_t pid;
    char string[20] = "Hello World\n";//string that I want to send to childs process

    int p = pipe( fdes ); //Creating pipe
    if( p < 0 )
        err( "pipe error\n");

    pid = fork(); //Creating process
    if( pid < 0 )
        err( "fork error\n" );

    if( pid == 0 ) //child
    {
        p = close( fdes[0] ); //Closing unused "write" end of pipe for child
        if( p < 0 )
            err( "close error\n" );

        char str[20]; //I save the message from parent in this string
        int p;
        p = read( fdes[1], str, strlen(str) );// Trying to receive the message and save it in str[]
        if( p < 0 )
            err( "read error\n" );

        printf( "Child received: %s\n", str );
    }
    else //parent
    {
        p = close( fdes[1] ); //Closing unused "read" end of pipe for parent
        if( p<0 )
            err( "close error\n");

        p = write( fdes[0], string, strlen( string ) ); //Trying to send the message to child process
        if( p < 0 )
            err( "write error\n" );

        printf( "Parent sent: %s\n", string );
        
        
    }
    return 0;
}
#包括
#包括
#包括
#包括
#包括
int err(const char*what)//写错误的函数
{
佩罗(什么);
出口(-1);
}
int main()
{
int fdes[2];//管道的文件描述符
pid_t pid;
char string[20]=“Hello World\n”;//我要发送到childs进程的字符串
int p=管道(fdes);//创建管道
if(p<0)
错误(“管道错误”\n);
pid=fork();//创建进程
if(pid<0)
错误(“fork error\n”);
if(pid==0)//子级
{
p=close(fdes[0]);//关闭子级未使用的“写入”管道末端
if(p<0)
错误(“关闭错误”\n);
char str[20];//我将来自父级的消息保存在此字符串中
INTP;
p=read(fdes[1],str,strlen(str));//尝试接收消息并将其保存在str[]
if(p<0)
错误(“读取错误”\n);
printf(“收到的子项:%s\n”,str);
}
else//parent
{
p=close(fdes[1]);//关闭父级管道未使用的“读取”端

如果(p您正在读取和写入错误的文件描述符。从:

pipefd[0]表示管道的读取端。pipefd[1]表示 写下管道的末端

read(2)
返回
EBADF
如果“
fd
不是有效的文件描述符或未打开进行读取”,同样,对于
write(2)
如果描述符未打开进行写入,则返回
EBADF


函数
int-pipe2(int-pipefd[2],int-flags);
返回2个文件描述符,以便

  • pipefd[0]
    指管道的读取端
  • pipefd[1]
    指管道的写入端

想想数组中对应于
STDIN\u FILENO
STDOUT\u FILENO
的文件描述符。你可以
0读取
(比如
STDIN\u FILENO
),并
写入1(比如
STDOUT\u FILENO
)。

注意:
p=read(fdes[1],strlen,strlen(str));
您正在对未初始化的字符数组调用strlen()。请使用
p=read(fdes[1],str,sizeof str)
在这里,或者只是
20
但是如果我更改stdin和stdout的标志,我是否能够正常使用printf和其他函数?它会在屏幕上显示printf的输出吗?如果我使用dup2函数更改文件描述符,我会得到与上面相同的结果吗?