首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在fork之后使用读/写的管道2字符串

在fork之后使用读/写的管道2字符串
EN

Stack Overflow用户
提问于 2021-11-24 18:49:51
回答 1查看 96关注 0票数 0

我很难理解在线课程中管道和叉子是如何协同工作的。首先,我想在printf和when all read/write end cat下面输入两个字符串作为一个字符串。我卡在读/写两个孩子,问题是它不符合我想要的,因为首先打印字符串,然后打开通道键入。也许这是一件小事,但我已经开始使用C进行在线课程了。读写功能是必需的。

代码语言:javascript
复制
String 1: 
sdfsdfsdf
String 2: 
Sdfsdfdsfsdfsd
String cat:
sdfsdfsdfSdfsdfdsfsdfsd

到目前为止,这是我的代码。

代码语言:javascript
复制
int main()
{
    int fd1[2],fd2[2];
    int status, pid;
    pipe(fd1);
    printf("String 1: \n");
    pid = fork();
    if(pid == 0)              /* child 1*/
    {
        close(fd1[0]);
        char cad1[100];
        read(0,&cad1,100);
        write(fd1[1],&cad1, 100);
        close(fd1[1]);
        exit(0);
    }
    else                          /* father*/
    {
        close(fd1[1]);
        printf("String 2: \n");
        pipe(fd2);
        pid = fork();
        if(pid == 0)               /* child 2 */
        {
            close(fd2[0]);
            close(fd1[0]);
            char cad2[100];
            read(0,&cad2,100);
            write(fd2[1],&cad2, 100);
            close(fd2[1]);
            exit(0);
        }
    }
    close(fd2[0]);
    /* wait every child */
    wait(&status);
    wait(&status);
    return 0;
}

我的输出如下:

代码语言:javascript
复制
String 1: 
String 2: 
cvbcvbcvbcvb
cvbcvbcvbcvb

为了cat我的代码(没有在代码中实现,我认为在cat之前调用两个管道到To char []变量。

任何建议来改进我的代码。提前谢谢。

EN

回答 1

Stack Overflow用户

发布于 2021-11-24 21:16:48

这是我的代码,大致基于您的代码。正如我在comment中所说的,父代码需要从两个管道中读取数据,以便从子管道中收集数据,然后将它们连接起来。您需要注意读取的字节数,以便写入的字节数不会超过读取的字节数。第二个子级应该同时关闭fd1[0]fd1[1],因为它不会使用它们。您需要担心换行符和空字节- read()返回的信息不是字符串,将包含换行符。

我选择使用fgets()来读取标准输入,因为它确实返回了一个字符串并删除了换行符。我也向标准输出中写入了一些信息。连接的字符串是使用snprintf()创建的。

代码语言:javascript
复制
#include <errno.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/wait.h>
#include <unistd.h>

static inline void syserr_exit(const char *fmt, ...)
{
    va_list args;
    int errnum = errno;
    va_start(args, fmt);
    vfprintf(stderr, fmt, args);
    va_end(args);
    if (errnum != 0)
        fprintf(stderr, "%d: %s\n", errnum, strerror(errnum));
    exit(EXIT_FAILURE);
}

int main(void)
{
    int fd1[2], fd2[2];
    int pid1, pid2;

    if (pipe(fd1) < 0 || pipe(fd2) < 0)
        syserr_exit("Failed to create two pipes: ");
    else if ((pid1 = fork()) < 0)
        syserr_exit("Failed to fork() child 1: ");
    else if (pid1 == 0)
    {
        /* Child 1*/
        close(fd1[0]);
        close(fd2[0]);
        close(fd2[1]);
        char cad1[100];
        printf("String 1: \n");
        fflush(stdout);
        if (fgets(cad1, sizeof(cad1), stdin) == NULL)
            syserr_exit("child 1 - failed to read from standard input: ");
        cad1[strcspn(cad1, "\r\n")] = '\0';
        write(fd1[1], cad1, strlen(cad1));
        /* Should error check the write! */
        printf("child 1 wrote [%s] to the parent process\n", cad1);
        close(fd1[1]);
        exit(0);
    }
    else if ((pid2 = fork()) < 0)
        syserr_exit("Failed to fork child 2: ");
    else if (pid2 == 0)
    {
        /* Child 1*/
        close(fd1[0]);
        close(fd1[1]);
        close(fd2[0]);
        printf("String 2: \n");
        fflush(stdout);
        char cad2[100];
        if (fgets(cad2, sizeof(cad2), stdin) == NULL)
            syserr_exit("child 2 - failed to read from standard input: ");
        cad2[strcspn(cad2, "\r\n")] = '\0';
        write(fd2[1], cad2, strlen(cad2));
        /* Should error check the write! */
        printf("child 2 wrote [%s] to the parent process\n", cad2);
        close(fd2[1]);
        exit(0);
    }
    else
    {
        /* Parent */
        char buffer1[100];
        char buffer2[100];
        close(fd2[1]);
        close(fd1[1]);
        ssize_t sz1 = read(fd1[0], buffer1, sizeof(buffer1));
        buffer1[sz1] = '\0';
        close(fd1[0]);
        ssize_t sz2 = read(fd2[0], buffer2, sizeof(buffer2));
        buffer2[sz2] = '\0';
        close(fd2[0]);

        size_t tlen = sz1 + sz2 + sizeof("[]+[]");
        char concat[tlen];
        snprintf(concat, sizeof(concat), "[%s]+[%s]", buffer1, buffer2);

        /* wait for both children */
        int s1, s2;
        int c1 = wait(&s1);
        int c2 = wait(&s2);

        printf("The one child (%d) exited with status 0x%.4X\n", c1, s1);
        printf("T'other child (%d) exited with status 0x%.4X\n", c2, s2);
        printf("Received from %d (%zu bytes) [[%s]]\n", pid1, sz1, buffer1);
        printf("Received from %d (%zu bytes) [[%s]]\n", pid2, sz2, buffer2);
        printf("Concatenated data: <<%s>>\n", concat);
    }
    return 0;
}

一个样本运行产生了:

代码语言:javascript
复制
$ ./pipe43
String 1: 
String 2: 
Vultures keep the world clean.
child 2 wrote [Vultures keep the world clean.] to the parent process
Hypersonic transport planes are as ubiquitous as pink elephants
child 1 wrote [Hypersonic transport planes are as ubiquitous as pink elephants] to the parent process
The one child (69005) exited with status 0x0000
T'other child (69004) exited with status 0x0000
Received from 69004 (63 bytes) [[Hypersonic transport planes are as ubiquitous as pink elephants]]
Received from 69005 (30 bytes) [[Vultures keep the world clean.]]
Concatenated data: <<[Hypersonic transport planes are as ubiquitous as pink elephants]+[Vultures keep the world clean.]>>
$
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70101468

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档