0

単純なfork()を使用してクライアント/サーバーをシミュレートし、次に非常に単純なパイプを使用して最大30の長さのcharバッファーを送受信しましたが、印刷できない文字(小さな「?」と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;
}

また、私が複数の単語を書くと、2番目の単語を忘れてしまいます。C ++ではgetl​​ine(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);

また、文字列には null ターミネータが含まれるようになり、最後にガベージが発生するのを防ぎます。

read (pipefd[0], &buf, strlen(buf))は初期化されていないため、使用できませんでしたbufstrlen文字列の最後にある終端の null を探し、見つかったら停止する単純な関数です。C++ ベクトルの関数とは異なりlength、C 関数にはメモリ メタデータにアクセスする方法がありません。(sizeofは演算子)

于 2012-06-08T04:11:15.267 に答える