我正在尝试从parent[0]
到child[1]
发送一个字符串。字符串的大小固定,因此每次长度都可以不同。
父母:
std::string x;
while(read(fd[WRITE_FD], &x, x.length()) > 0)
{
cout<< x;
}
答案 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字节结尾的数据块为止。