2017-12-11 15 views
0

パイプを使ってbcを使ってchar式の答えを得ようとしています。 最初に式をpipe1に書くと、bcはパイプ2で答えを読み書きします。このために、私は入力と出力を変更しています。パイプとフォークを使ってbcを使う

write(pipe1[1], "20*5\n", sizeof("20*5\n")-1) != sizeof("20*5\n")-1) 

しかし、私はタブを宣言した場合、私はエラーを取得しておく:たまに

(standard_in) 2: illegal character: ^@ 

私は[]のcharを使用し、ちょうど書き込みに式を入れていない場合、これは作業を行います2の代わりに1になります

私は間違っていますか?誰かが私に説明できるなら、ありがとう。

コード:

#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 

int main(void) 
{ 
    char resultat[5]; 
    int pipe1[2]; 
    int pipe2[2]; 

    pipe(pipe1); 
    pipe(pipe2); 

    int resultat_fork = fork(); 

    if (resultat_fork == -1) 
    { 
     exit(EXIT_FAILURE); 
    } 

    char* expression = "20*5\n"; 

    if (resultat_fork != 0) 
    { 
     //printf("I am the parent\n"); 

     close(pipe1[0]); 
     close(pipe2[1]); 

     if (write(pipe1[1], expression, sizeof(expression)) != sizeof(expression)) 
      fprintf(stderr, "write to child failed\n"); 

     int nbytes = read(pipe2[0], resultat, sizeof(resultat)); 
     if (nbytes <= 0) 
      fprintf(stderr, "read from child failed\n"); 
     else 
      printf("resultat: %.*s\n", nbytes, resultat); 

     close(pipe1[1]); 
     close(pipe2[0]); 
    } 
    else 
    { 
     printf("I am the child\n"); 

     close(pipe1[1]); 
     close(pipe2[0]); 
     dup2(pipe1[0], 0); 
     dup2(pipe2[1], 1); 
     close(pipe1[0]); /* More closes! */ 
     close(pipe2[1]); /* More closes! */ 

     execlp("bc", "bc", NULL); 
     fprintf(stderr, "Failed to execute bc\n"); 
     exit(EXIT_FAILURE); 
    } 
    return 0; 
} 
+0

変数 'expression'はポインタであり、配列ではありません。 'sizeof'の代わりに' strlen() 'を使います。 (私はこの質問の以前の変形に対する私の以前の答えに対する解説で 'strlen()'を使って言及しました) –

+0

申し訳ありません、私の謝罪を受け入れてください。 – Karl

+0

謝罪が受け入れられました - 解説のデリタスの中で有用な情報のナゲットを検出するのは難しいでしょう(答えの中と後の両方)。 –

答えて

1

^@はNUL文字すなわち'\0'です。これは、あなたがbcに書き込むときに、文字列の最後をオーバーランさせることを示唆します。問題はここにある:

sizeof(expression) 

expressionが配列ではない、それは文字列"20*5\n"の最初の文字を指すcharポインタであると、あなたは64ビットマシン上にある場合、そのサイズは8です。送信する文字列の長さを取得するには、代わりにstrlen(expression)を使用してください。

あなたの問題に関係しないもう1つのことは、親プロセスで、答えを読んだ後で、子プロセスが完了するためにwaitです。それ以外の場合は、ゾンビが残っています。

+0

お返事ありがとうございます、私はお待ちください。 – Karl

+0

親プロセスが子プロセスの前に終了した場合、システムプロセス(通常はPID 1、 'init')は孤立した子プロセスを継承し、ゾンビを生成しないことに注意してください。あなたがゾンビを取得する唯一の時間は、親プロセスが子プロセスが終了するまで終了しない場合ですが、親プロセスはどのステージでも子プロセスを待機しません。親が多くのゾンビを作成する場合、これは問題になります。 1つのゾンビはめったに問題にならず、多くのプロセスがかなり迅速に終了するので、ゾンビは自動的にシステムによってクリーンアップされます。 –

1

これは、あなたのシステムが32ビットであれば、それはあなたの中に任意のポインタ変数のサイズである、4になり、char*あるexpressionsizeof演算子を使用している間違った

if (write(pipe1[1], expression, sizeof(expression)) != sizeof(expression)) 

ですコード。

sizeofの代わりにstrlen(expression)を使用する必要があります。

答えにも指摘されているように、親プロセスに複数の子プロセスがある場合は、子プロセスが実行を終了して終了する必要があります。理想的には、返り値waitもチェックする必要があります。これにより、子プロセスがどのように終了したかの詳細がわかります。

+0

申し訳ありませんが、私もこれを試してみましょう、助けてくれてありがとう、ずっと便利です。 – Karl

関連する問題