既然你不记录了多少字节读出的管道,你的代码是印刷已经在ch
变量的垃圾。有很多方法来处理它。这段代码显示了其中两个。我使用memset()
来确保ch
包含一些数据(并且分配确保它是空终止的)。
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
int main(void)
{
pid_t pid;
int fds[2];
int ret;
char ch[20];
memset(ch, 'X', sizeof(ch)-1);
ch[sizeof(ch)-1] = '\0';
ret = pipe(fds);
if (ret == -1)
{
perror("pipe failed");
exit(0);
}
pid = fork();
if (pid == 0)
{
printf("Child process\n");
write(fds[1], "Hello", 5);
}
else if (pid > 0)
{
printf("Parent Process\n");
int nbytes = read(fds[0], ch, 15);
printf("[%s]\n", ch);
printf("[%.*s]\n", nbytes, ch);
ch[nbytes] = '\0';
printf("[%s]\n", ch);
}
else
fprintf(stderr, "fork() failed\n");
return 0;
}
代码记录了多少字节写入(真正勤奋的代码将确保正确的数据量是书面的,太)。它打印数据3次 - 一次使用原始技术,然后一次使用从管道读取的字节数来限制输出,然后空数据终止,以便它可以写成一个简单的字符串。
%.*s
转换规范使用两个值 - 数字和字符串。该数字是将要写入的最大字节数。如果字符串比这短,那就这样吧。如果字符串更长,超出的字节将被忽略。
示例输出:
Parent Process
[HelloXXXXXXXXXXXXXX]
[Hello]
[Hello]
Child process
这是管道的程序输出的结果。在视觉上,在终端上,我通常得到:
Parent Process
Child process
[HelloXXXXXXXXXXXXXX]
[Hello]
[Hello]
两个输出都有效。注意数据的第一次打印是如何包含一些X的,因为没有从管道读取空字节。
另一种替代方法是让孩子将空字符结尾的字符串写入管道:write(fds[1], "Hello", sizeof("Hello"));
。其他选项包括在管道上写入字符串的长度,然后读取数据,然后读取长度和许多字节的数据。这是TLV(类型,长度,值)编码系统的一个小变体 - 类型没有明确指定,因为它被假定为char
。
欢迎来到Stack Overflow。 请注意,在这里说'谢谢'的首选方式是通过 提高投票的好问题和有用的答案(一旦你有足够的声誉这样做),并接受任何 问题最有用的答案,你问(这也给你一个小小的提升,以你的声望 )。 请参阅[关于]页面,以及[如何在此处提问 ?]和 [当有人回答我的 问题时,我该怎么办? ?](http://stackoverflow.com/help/someone-answers) –