2

これは、私が行っている一連の演習の 1 つのステップです。私が書くプログラムは、3 つ以上の引数を取る必要があります。最初の引数の使用はまだ実装されていません。残りの引数はディレクトリのリストです。

このステップでは、引数で指定されたディレクトリごとに cat のインスタンスを作成し、cat を使用して各ディレクトリのすべてのファイルの内容を取得し、内容を出力する必要があります。/home/directory と /home/directory/ の両方のパスを処理できるはずです (最後の / がある場合とない場合)。

現在私がやっていることは、指定されたディレクトリ内のすべてのファイルを読み取り、それらのコンテンツを返すように、引数 /home/directory/* を指定して cat を実行しようとしています。これは私のコードです:

#include "Step1.h"

int main(int argc,char* argv[])
{
    if(argc < 3)
    {
        printf("Usage: ./Step1 <exclusions file> <folder1> <folder2> <folder3> ...\n");
        return -1;
    }

    int i;
    for(i=2; i<argc; i++)
    {
        int catpipe[2];
        if(pipe(catpipe))
        {
            printf("Error in pipe\n");
            return -1;
        }
        pid_t pid = fork();
        if(pid < 0)
        {
            printf("Error in fork\n");
            return -1;
        }
        if(!pid)
        {
            dup2(catpipe[1],1); // cat pipe is used to get the output of cat program into this program.
            close(catpipe[1]);
            close(catpipe[0]);
            char* args[3];
            args[0] = "/bin/cat";
            int length = strlen(argv[i]);
            char* path;
            if(argv[i][length - 1] != '/') // the path given does not have the ending / 
            {
                path = malloc(length + 3);
                strcpy(path,argv[i]);
                path[length] = '/';      //append / at the end
                path[length+1] = '*';    // append * at the end
                path[length+2] = '\0';
            }
            else
            {
                path = malloc(length + 2); // the path contains the ending /
                strcpy(path,argv[i]);
                path[length] = '*';        // append * at the end
                path[length+1] = '\0';
            }                 
            args[1] = path;
            args[2] = NULL;
            printf("%s\n",path);
            execvp("/bin/cat",args);
        }
        close(catpipe[1]);
        char buffer[200];
        int total = read(catpipe[0],buffer,200); // read the output of cat program and print it. 
        buffer[total]='\0';
        printf("The buffer contains: %s\n",buffer);
    }
    return 0;
}

このコードを次のように実行しました。

mod@mod-Inspiron-N5110:~/project$ ./Step1 exclusions ./testdirectory1 ./testdirectory2/

私が得た結果は次のとおりです。

/bin/cat: ./testdirectory1/*: No such file or directory
The buffer contains: 
The buffer contains: ./testdirectory2/*

mod@mod-Inspiron-N5110:~/project$ /bin/cat: ./testdirectory2/*: No such file or directory

mod@mod-Inspiron-N5110:~/project$

しかし、私がするとき:

mod@mod-Inspiron-N5110:~/project$ /bin/cat ./testdirectory1/*

結果は次のとおりです。

Testline 1 of testfile1 in testdirectory1
Test line 1 of testfile1 in testdirectory1
Testline 1 of testfile2 in testdirectory1
Testline 1 of testfile3 in testdirectory1

私のプログラムでこの結果を得るのを手伝ってください。

前もって感謝します

4

2 に答える 2

1

私は自分の質問に対する答えを見つけたと思います。私は、私のような誰かがいつか役に立つと思うと信じてこれを投稿しています. しかし、私はまだCがあまり得意ではありません。したがって、この回答が間違っている場合、またはこれに間違いや弱点がある場合は、遠慮なく修正してください。

私の答えの鍵は、 function を使用することwordexp()です。指定されたパス (チルダ、正規表現、変数、およびすべて) を展開するために使用できます。これが私の答えです:

#include "Step1.h"

int main(int argc,char* argv[])
{
    if(argc < 3)
    {
        printf("Usage: ./Step1 <exclusions file> <folder1> <folder2> <folder3> ...\n");
        return -1;
    }

    int i;
    for(i=2; i<argc; i++)
    {
        int catpipe[2];
        if(pipe(catpipe))
        {
            printf("Error in pipe\n");
            return -1;
        }
        pid_t pid = fork();
        if(pid < 0)
        {
            printf("Error in fork\n");
            return -1;
        }
        if(!pid)
        {
            dup2(catpipe[1],1); // cat pipe is used to get the output of cat program into this program.
            close(catpipe[1]);
            close(catpipe[0]);

            int length = strlen(argv[i]);
            char* path;
            if(argv[i][length - 1] != '/') // the path given does not have the ending / 
            {
                path = malloc(length + 3);
                strcpy(path,argv[i]);
                path[length] = '/';      //append / at the end
                path[length+1] = '*';    // append * at the end
                path[length+2] = '\0';
            }
            else
            {
                path = malloc(length + 2); // the path contains the ending /
                strcpy(path,argv[i]);
                path[length] = '*';        // append * at the end
                path[length+1] = '\0';
            }            

        wordexp_t p;
        char **w;
            wordexp(path, &p, 0);
        char** args = malloc((p.we_wordc + 2) * sizeof(char*));
            args[0] = "/bin/cat";   
        w = p.we_wordv;
        int j;
        for (j = 0; j < p.we_wordc; j++)
        args[j+1] = w[j];                
            args[p.we_wordc + 1] = NULL;

            execvp("/bin/cat",args);
        }
        close(catpipe[1]);
        char buffer[1024];
        int total = read(catpipe[0],buffer,1024); // read the output of cat program and print it. 
        buffer[total]='\0';
        printf("The buffer contains: %s\n",buffer);
    }
    return 0;
}
于 2014-01-28T15:51:19.720 に答える
0

したがって、基本的にコードで間違っているのは/directory/*、 に引数として を指定するとcatcatそれが「多数のファイル」として展開されると想定しているのに対し、catは というファイルを開きたいことを理解していることです*

*拡張を行う簡単な方法は、シェルを介して cat を呼び出すことです。これにより*、「多数のファイル」からの拡張が行われます。

これを実現するには、あなたexecvp()system(…)call に置き換えることができます。これは基本的execl("sh", "sh", "-c", …, NULL)に ... がコマンドです (つまり、単純に呼び出すことができ、シェルによって展開される必要があります"/bin/sh", "-c", "/bin/cat", "/directory/*")*

または、そのような独自の再帰的なディレクトリ ウォーク アルゴリズムを使用することもできます。

于 2014-01-26T14:39:32.727 に答える