为什么从管道中读取会产生垃圾值?

时间:2016-03-17 00:48:39

标签: c pipe system-calls

// Some code for initialization

int fd[2];
pipe(fd);
int k = fork();

if (k == 0) {    // Child
    dup2(fd[1], fileno(stdout));
    execl("someExecutable", NULL);    // The executable just printfs one line
}
else if (k > 0) {    // Parent
    wait(&status);
    while (read(fd[0], buffer, 1) > 0) {
        printf("%s", buffer);
    }
}

我省略了错误检查。

首先,如果我的可执行文件有printf("some line\n");,则屏幕上的输出看起来像s?9o?9m?9e?9 ?9l?9i?9n?9e?9。为什么中间有这些随机字符?

其次,我的阅读永远不会结束。当可执行文件结束时,管道的读取端应该关闭吗?

谢谢。

3 个答案:

答案 0 :(得分:1)

您必须将{指针)以null结尾的字符串传递给%s中的printf()格式说明符。

要打印一个字符,请使用%c

while (read(fd[0], buffer, 1) > 0) {
    printf("%c", *buffer);
}

答案 1 :(得分:1)

您正在打印二进制数据。以下

 while (read(fd[0], buffer, 1) > 0) {
    printf("%s", buffer);
}

将打印直到它变为NULL,即' \ 0'。试试这个

 while (read(fd[0], buffer, 1) > 0) {
    printf("%.*s", 1, buffer);
}

此代码可能有助于说明有关printf和null终止字符串的观点......

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

int main(void) {
  srand(time(NULL));
  size_t n = 0;
  //First we create some random data. 
  //Lets assume this is our binary stream
  char *str_cpy = malloc(1024);
  n = 0;
  while(n++ < 1024) {
    str_cpy[n] = rand() % 255;
  } 
  //We have a known string we want to print
  const char *str = "foobar";
  printf("%s\n", str); 
  memcpy(str_cpy, str, 6);//Ooops: forgot to copy the null terminator 
  size_t str_len = strlen(str_cpy);
  // This is unlikely to print 6
  printf("%zu\n", str_len);
  //This is undefined behavior
  printf("%s\n", str_cpy);
  free(str_cpy);
  return 0;
}

答案 2 :(得分:0)

如果你的缓冲区被声明为char缓冲区,那么在read()中传递一个指针,如果它被声明为buffer [],那么你可能想要将大小作为参数传递而不是1,因为你是已检查read()的状态,如果成功,则应返回读取的字节数。现在更改printf(&#34;%c&#34; ...)或printf(&#34;%s&#34; ...)。