如何使用管道将字符串从子级发送到父级

时间:2018-10-19 02:09:10

标签: c++ string pipe

我正在尝试从parent[0]child[1]发送一个字符串。字符串的大小固定,因此每次长度都可以不同。

父母:

std::string x;
while(read(fd[WRITE_FD], &x, x.length()) > 0)
    {
      cout<< x;
    }

1 个答案:

答案 0 :(得分:0)

std::string不适合作为read的第二个参数。您需要传递read缓冲区,将其数据以及要从管道读取的字节数写入缓冲区。

如果首先将字符串的长度写入管道,则将使您的生活变得更加简单。这样,您可以知道要从管道读取多少字节:

int main() {
    int fd[2];
    pipe(fd);

    pid_t pid = fork();
    if (pid == 0) {
        close(fd[0]);
        std::string str = "some data";
        std::string::size_type size = str.size();
        write(fd[1], &size, sizeof(size));
        write(fd[1], str.c_str(), str.size());
    } else {
        close(fd[1]);
        std::string::size_type size;
        read(fd[0], &size, sizeof(size));
        std::string str(size, ' ');
        // This depends on the fact that the pointer returned by data
        // is non-const in C++17.
        // Use &str[0] instead of str.data() if using an older C++ standard
        read(fd[0], str.data(), size);
    }
}

在此示例中,子进程首先将字符串的长度写入管道,然后将字符串数据本身写入(值得注意的是,它没有将nul终止符写入管道)。然后,父级读取该长度,分配一个适当大小的字符串,然后将数据读入该字符串管理的缓冲区。


如果您不想首先写入字符串的长度,则必须一次读取一个块,直到找到一个以nul字节结尾的块:

int main() {
    int fd[2];
    pipe(fd);

    pid_t pid = fork();
    if (pid == 0) {
        close(fd[0]);
        std::string str = "some data";
        write(fd[1], str.c_str(), str.size() + 1);
    } else {
        close(fd[1]);
        std::string str;
        while (true) {
            char c[100];
            ssize_t count = read(fd[0], c, 100);
            if (c[count - 1] == '\0') {
                // Don't copy an extra nul terminator into the string object
                str.append(c, c + count - 1);
                break;
            } else {
                str.append(c, c + count);
            }
        }
    }
}

在此示例中,子进程使用nul终止符将字符串数据写入管道。然后,父进程从管道中读取100字节的数据块,并将数据追加到字符串,直到读取以nul字节结尾的数据块为止。

相关问题