代わりに、標準入力のからの入力を取るために、パイプファイルを受け入れるwcを作る方法?

kronaemmanuel:

これは宿題の問題です。タスクは、コマンドを複製することです:ls | wc -l使用してCプログラムではexeclpforkとのパイプを。

私のアプローチ

私はこの問題は、この方法で解決することができると思います:

  1. パイプファイルを作成します。 pipe.txt
  2. 使用して子プロセスを作成します。 fork()
    • マップstdoutに子プロセスのをpipe.txt
    • 実行ls使用execlp
    • これは、出力のを置くlspipe.txt
  3. 親プロセスの内部
    • マップstdinに親プロセスのをpipe.txt
    • 実行wc -l使用してexeclp、それは代わりに標準入力から読み込むように、任意の更なる引数を与えることなく
    • 以来stdout、それは、端末上の行数をプリントアウトする必要がありますので、この親プロセスのは、まだ、端末そのものであります

マイコード

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h> 
#include <fcntl.h> 
#include <errno.h> 
#include <sys/wait.h>

int main() {
        int pipefds[2];
        int returnstatus;
        int pid;

        char argArr[30] = {'\n'};

        returnstatus = pipe(pipefds);
        if (returnstatus == -1) {
                printf("Unable to create pipe\n");
                return 1;
        }

        int file_desc = open("pipe.txt", O_RDWR | O_APPEND | O_CREAT); 

        pid = fork();

        if (pid == 0) {
                int copy_desc = dup2(file_desc, 1);
                execlp("ls", "ls", NULL);
        } else {
                int copy_desc = dup2(file_desc, 0);
                close(copy_desc);
                execlp("wc", "wc", "-l", NULL);
        }
        return 0;
}

実際の出力

main.cpp blabla.cpp main pipe.txt
>

問題

これで間違っている二つのこと:

  1. 私はあることを子供の標準出力を設定しているのでpipe.txt、ファイル、なぜそれが端末上で、まだ出力していますか?注:これは、出力を入れないpipe.txt、あまりにもファイル。しかし、なぜそれはあまりにも、端末に表示されていますか?

  2. これは、ユーザーが入力を提供するために、待ちの状態になりますか?それは、パイプファイルの代わりに、ユーザからの入力を取得するべきではないでしょうか。

予想される出力

5

*現在のディレクトリ内の5つのファイルが存在する場合

試したソリューション

  1. ただパイプを使用した:(不正なファイルディスクリプタのエラーを得ました)
int main() {
        int pipefds[2];
        int returnstatus;
        int pid;

        returnstatus = pipe(pipefds);
        if (returnstatus == -1) {
                printf("Unable to create pipe\n");
                return 1;
        }

        pid = fork();

        if (pid == 0) {
                dup2(pipefds[0], 1);
                close(pipefds[1]);
                execlp("ls", "ls", NULL);
        } else {
                dup2(pipefds[1], 0);
                close(pipefds[0]);
                execlp("wc", "wc", "-l", NULL);
        }
        return 0;
}

kronaemmanuel:

有益なコメントをありがとう。

コード内の問題は、私はすべてのパイプを使用していないということです。私は私が作成したファイルにすべての私の仕事をしていました。ように基本的な問題でした。

ここで、新しいコードは次のとおりです。

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h> 
#include <fcntl.h> 
#include <errno.h> 
#include <sys/wait.h>

int main() {
    // Step1. Create pipe file descriptors: pipefd[0] for reading from pipe, pipefd[1] for writing to the pipe
    int pipefds[2];

    // Helping variables
    int returnstatus;
    int pid;

    // Step2. Create a pipe with the file descriptors
    returnstatus = pipe(pipefds);

    // Check if pipe was successfully created
    if (returnstatus == -1) {
        printf("Unable to create pipe\n");
        return 1;
    }

    // Step3. Fork to create a child process
    pid = fork();

    if (pid == 0) {
        // Inside the child process

        // Step4. Duplicate the file descriptor of the write end of the pipe and set it equal to the stdout of the process 
        dup2(pipefds[1], 1);

        // Step5. Close both ends of the pipe
        close(pipefds[0]);
        close(pipefds[1]);

        // Step6. Execute the LS command. It ouputs to stdout which we set equal to the pipe in Step4.
        // So essentially, we send all output of ls to our pipe 
        returnstatus = execlp("ls", "ls", NULL);

        // Error checking the execlp command
        if (returnstatus == -1){
            perror("Error executing execlp: ");
        }
    } else {
        // Inside the parent process

        // Step7. Duplicate the file descriptor the READ end of the pipe and set it equal to the stdin of the process
        dup2(pipefds[0], 0);

        // Step8. Close the both ends of the pipe
        close(pipefds[0]);
        close(pipefds[1]);

        // Step9. Execute the WC command. It takes the file as an argument usually but if no file is given, it will take
        // stdin as input. Since the stdin is the pipe, therefore it will read all the data from the pipe.
        // The output of the wc command is stdout which is the terminal for this process so we will get the number of
        // files/directories in the current directory as an output on the terminal
        returnstatus = execlp("wc", "wc", "-l", NULL);

        // Error checking the execlp command
        if (returnstatus == -1){
            perror("Error executing execlp: ");
        }
    }
    return 0;
}

おすすめ

転載: http://43.154.161.224:23101/article/api/json?id=26396&siteId=1