4

今日、C で pipe() と fork() と exec() を使い始めましたが、今問題があります:

メイン プログラムは、2 つのパイプとフォークを作成します。子プロセスは別のプログラムに対して exec() を実行します。このプログラムは現在、stdin から読み取り、親と通信し、stdout を介して結果を書き込むテスト プログラムにすぎません。メイン プログラムは、データを受信し、SQLite 3 データベースと通信し、パイプを使用してデータを返すことになっています。問題のこの部分は解決され、パイプは適切に開閉され、通信が行われます。

次に、問題は、ある時点で子プロセス(exec()で呼び出されるプロセス)で、これがあります:

printf("Strid sent: %s\n", strid);
write(4,strid,sizeof(strid));

printf("Str sent: %s\n", str);
write(4,str,sizeof(str));

そして、親はこの部分で適切に読んでいるはずです:

read(select[0],strid, sizeof(strid));
printf("Strid recived: %s\n",strid);
int id = atoi(strid);
printf("Id recived: %d\n",id);

read(select[0],buffer, sizeof(buffer));
printf("Buffer recived: %s\n",buffer);

しかし、これらのprintfで私が受け取ったのは次のとおりです。

Strid sent: 1
Str sent: start
Strid recived: 1
Id recived: 1
Buffer recived: 7� (and other strange characters)

ご覧のとおり、問題は 2 番目のコマンドの受信にあります (その部分はそのままコピーされ、他のコードは含まれていません)。

str を受け取る「buffer」変数は char buffer[20] として宣言されており、read() の前に使用されていないことも言わなければなりません。

前もって感謝します!

4

2 に答える 2

3

0読み取った後、印刷する前に、最後に終了バイトを追加する必要があります。

int len = read(select[0], buffer, sizeof(buffer) - 1);
if (len < 0) {
    perror("read error");
} else {
    buffer[len] = 0;
    printf("Buffer recived: %s\n", buffer);
}

したがって、重要なことは、使用する前に、のマニュアルページ、または実際に任意の関数のマニュアルページを読んでください...read

または、おそらく行ごとの読み取りが問題ない場合は、 stdio.h関数を使用します。0fgets

于 2013-02-13T21:26:58.083 に答える
0

パイプは、書き込み間の「境界」を追跡しません。そのため、パイプに複数の書き込みがある場合、それらの書き込みからのすべてのデータが 1 回の読み取りに応答して返される可能性があります。そのため、文字列 (たとえば) の後に整数を送信し、その文字列をバッファーに読み取ろうとすると、文字列とそれに続く整数の両方がバッファーに取り込まれ、文字列の末尾がゴミのように見えます。 、および read によって返されるサイズは大きくなります。

さらに、パイプがいっぱいになると、要求されたすべてのデータが書き込みで書き込まれない可能性があります。現時点で収まる量だけが書き込まれ、後で残りを書き込む必要があります。

readそのため、との呼び出しの戻り値を常にチェックし、予想よりwriteも少ない (または多い) 取得に対処する準備をしてください。read

于 2013-02-13T21:49:41.397 に答える