2

Cでパイプメッセージを書く方法を学ぶための簡単なプログラムを書きましたが、それをしているときに、説明も理解もできない奇妙なものを見つけました。これがコードです:

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

#define MAXSIZE 100
int fd[2];

void writeMsg() {
    int i;
    char message[MAXSIZE];
    for (i = 0; i < 12; i++) {
        sprintf(message,"%d%d%d%d%d%d%d%d%d%d\n",i,i,i,i,i,i,i,i,i,i);
        write(fd[1], message, strlen(message));
    }
}

int main() {
    pipe(fd);
    char message[MAXSIZE];
    int pid;
    pid = fork();
    if (pid == 0) {
        writeMsg();
    }
    if (pid > 10) {
        wait(NULL);
        read(fd[0], message, MAXSIZE);
        printf("%s", message);
    }
    return 0;
}

writeMsg には、パイプに MAXSIZE より大きいメッセージを書き込むループがあります。その後、メッセージが読み取られてメインに出力されます。奇妙なことに、次のメッセージで使用するstrlen(message)write(fd[1], message, strlen(message))出力されます。

0000000000
1111111111
2222222222
3333333333
4444444444
5555555555
6666666666
7777777777
8888888888
9

しかし、代わりwrite(fd[1], message, strlen(message)+1)にメッセージを使用する場合は次のとおりです。

0000000000

strlen(message)とはどう違いstrlen(message)+1ますか?ここhttp://codewiki.wikidot.com/c:system-calls:writeでは、書き込むバイト数が提供されたバッファーよりも小さい場合、出力は切り捨てられると言われていますが、+1 の場合、文字列のサイズは11、これは MAXSIZE 以下です。明確化や修正は大歓迎です。

4

2 に答える 2

2

+1 を指定すると、文字列の最後 (改行の後) にあるゼロが送信されます。つまり、反対側のバッファーを印刷するとprintf、最初の行の後に停止します。あなたは本当にそのゼロを送りたくないので、そうしないでください...

パイプを介して文字列の末尾にゼロが本当に必要な場合は、各文字列がどこで終了するかを把握し、それらを個別に出力する必要があります。たとえばstrlen()、メッセージの長さを把握するために使用し、移動するインデックスを使用します。index += strlen(&message[index])+1、そしてprintf("%s", &message[index]);すべてを印刷するまでループします(インデックスと読んだ量を比較してください!)。

0 バイトを返すまでループを使用するreadと、すべての入力を読み取ることができます (現在の読み取りが短すぎるため、すべての 9 を取得していません)。

于 2013-08-14T23:33:51.700 に答える
2

何が起こっているのかというwritestrlen(message) + 1\0キャラクターで呼び出すときも書いてあります。

つまり、read()ingすると\0、char の配列に追加されます。printf()が見つかると停止するため\0、最初の呼び出しで書き込まれたテキストのみが に出力されるのはこのためwrite()です。

于 2013-08-14T23:32:45.607 に答える