0

我使用了一个简单的 fork() 来模拟客户端/服务器,然后使用一个非常简单的管道来发送/接收最大 30 长度的字符缓冲区,但它最终打印出不可打印的字符(小“?”和一个带有 4 个 1 和 0 的框)在所需单词之后。

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <string.h>

int main () {
    int pipefd[2];
    int cpid;
    char buf[31];
    if (pipe(pipefd) == -1) {
        perror("pipe");
        exit(EXIT_FAILURE)
    }
    cpid = fork();
    if (cpid == -1) P
        perror("cpid");
        exit(EXIT_FAILURE);
    }
    if (cpid == 0) {      // child reads from pipe
        close (pipefd[1]); // close unused write end
        read (pipefd[0], &buf, 30); // if I use 30 instead of strlen(buf) it prints Server transmit: Server receives. It does not wait for write. Makes no sense
        printf ("Server receives: %s", buf);
        close (pipefd[0])l
        exit (EXIT_SUCCESS);
    }
    else {               // parent writes to pipe
        close (pipefd[0]); // closing unused read end;
        char buf2[30];
        printf("Server transmits: ");
        scanf ("%s", buf2);
        write (pipefd[1], buf2, strlen(buf2));
        close(pipefd[1]);
        wait(NULL);
        exit(EXIT_SUCCESS);
    }
  return 0;
}

此外,如果我写了一个以上的单词,它就会忘记第二个。在 c++ 中,我使用了 getline (cin, string) 但这不是一个选项。

也使用过read (pipefd[0], &buf, sizeof(buf));,现在它以正确的顺序打印(不知道为什么 strlen 不起作用)但最后我仍然得到不可打印的字符。

4

1 回答 1

3

write (pipefd[1], buf2, strlen(buf2));您忽略将其放入'\0'流中时。将其更改为:

write (pipefd[1], buf2, strlen(buf2)+1);

你的字符串现在将包含空终止符,防止最后出现垃圾。

read (pipefd[0], &buf, strlen(buf))由于buf未初始化,使用无效。strlen是一个简单的函数,它在字符串末尾查找终止的空值,找到后停止。与lengthC++ 向量的函数不同,C 函数无法访问内存元数据。(sizeof是运算符)

于 2012-06-08T04:11:15.267 回答