既然你不記錄了多少字節讀出的管道,你的代碼是印刷已經在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) –