0

ファイルから読み取り、パイプに書き込み、子プロセスでパイプから読み取り、新しいファイルに書き込もうとしています。プログラムには、入力ファイルの名前とコピー先のファイルの名前の 2 つのパラメーターが渡されます。これは宿題のプロジェクトですが、私はオンラインで何時間も費やし、混乱を招く方法しか見つけませんでした. これとスレッドによる行列乗算の 2 つの割り当てが与えられました。問題なく行列の乗算を取得しましたが、これはかなり簡単なはずですが、非常に問題があります。コピーしているファイルの最初の単語を取得しますが、その後、大量の文字化けが発生します。

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

int main(int argc, char *argv[]) {

    if(argc < 3) {
        printf("Not enough arguments: FileCopy input.txt copy.txt\n");
        exit(0);
    }
    char buffer[200];

    pid_t pid;
    int fds[2];

    pipe(fds);
    pid = fork();


    if (pid == 0) { /* The child process */
        //wait(NULL);
        write(1, "hi i am in child\n", 17);
        int copy = open(argv[2], O_WRONLY | O_CREAT, S_IWUSR | S_IRUSR | S_IXUSR | S_IRGRP);
        FILE* stream;
        close(fds[1]);

        stream = fdopen(fds[0], "r");
        while (fgets(buffer, sizeof(buffer), stream) != NULL) {
            //printf("%s\n", buffer);
            write(copy, buffer, 200);
            //printf("kjlkjljljlkj\n");
            //puts(buffer);

        }

        close(copy);
        close(fds[0]);

        exit(0);

    }
    else {
        write(1, "hi i am in parent\n", 18);
        FILE* input = fopen(argv[1], "r");
        FILE* stream;
        close(fds[0]);
        stream = fdopen(fds[1], "w");
        /*while (fscanf(input, "%s", buffer) != EOF) {
            //printf("%s\n", buffer);
            fprintf(stream, "%s\n", buffer);
            fflush(stream);
            //printf("howdy doody\n");
        }*/
        fgets(buffer, sizeof(buffer), input);
        printf("%s", buffer);
        fprintf(stream, "%s", buffer);
        fflush(stream);
        close(fds[1]);
        fclose(input);
        wait(NULL);
        exit(0);
    }
    return 0;
}

読み取りと書き込みを間違っていますか?

4

2 に答える 2

2

読み取りと書き込みを間違っていますか?

はい。

子では、文字列指向のバッファ I/O (fgets()) とブロック指向のバイナリ I/O を混在させています。(つまり、write()。) どちらの方法でも機能しますが、どちらか一方を選択するのが通常の方法です。

それらを混在させると、問題のより多くの側面を考慮する必要があります。たとえば、子プロセスでは、パイプから 1 行だけを読み取っていますが、バッファ全体をファイルに書き込みます。これが、おそらくファイル内で見られる文字化けの原因です。

親では、ループなしで 1 行だけを送信しています。その後、バッファリングされた I/O システムを fclose() する前に、基礎となるファイル記述子を閉じます。これは、fclose がバッファーをフラッシュしようとすると、現在閉じられている記述子は残りのデータを書き込むために機能しないことを意味します。

Posix で指定されたカーネル レベルの操作である write()/read()/close() を使用するか、ISO C で指定された標準 I/O ライブラリである fdopen/puts/gets/fclose を使用できます。オペレーション。さて、うまくいくそれらを混合する1つの方法があります。親で stdio を使用する場合でも、子で読み取り/書き込みを使用できますが、各行に対してカーネル呼び出しを行うことになり、通常は理想的な方法ではありません。

于 2013-02-20T15:30:48.507 に答える