2

私は現在、最初は引数を取るように設計されたコード例を使用しており、現在のディレクトリでその引数を検索します。「」を置き換えて、別のディレクトリ(正確には/ dev / shm)を検索するようにしました。 「」「/dev/ shm」を使用しますが、何かを検索してもコードは何も表示されません*(ワイルドカードに注意してください)。ワイルドカード検索は現在のディレクトリで正常に機能するので、問題はワイルドカードではないと思います。誰かが私を助けてくれたら、本当にありがたいですが、ありがとう!

#include <dirent.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>


static void lookup(const char *arg)
{
    DIR *dirp;
    struct dirent *dp;


    if ((dirp = opendir(".")) == NULL) {
        perror("couldn't open '.'");
        return;
    }


    do {
        errno = 0;
        if ((dp = readdir(dirp)) != NULL) {
            if (strcmp(dp->d_name, arg) != 0)
                continue;


            (void) printf("found %s\n", arg);
            (void) closedir(dirp);
                return;


        }
    } while (dp != NULL);


    if (errno != 0)
        perror("error reading directory");
    else
        (void) printf("failed to find %s\n", arg);
    (void) closedir(dirp);
    return;
}


int main(int argc, char *argv[])
{
    int i;
    for (i = 1; i < argc; i++)
        lookup(argv[i]);
    return (0);
}
4

2 に答える 2

6

opendirワイルドカードは処理しません。実際のディレクトリパスが必要です。あなたが言うときあなたが何を意味するのかわかりません

ワイルドカード検索は現在のディレクトリで機能します

それがあなたのシェルで機能することを意味するなら、それは予想されることです。シェルは最初にワイルドカードを展開し、次に入力したコマンドを実行します。

では、これをどのように解決するのでしょうか?globを呼び出す前に、使用してワイルドカードを自分で展開しますopendir


編集:申し訳ありませんが、ディレクトリ名のワイルドカードを一致させようとしていると思いました。ワイルドカードを使用してディレクトリの内容を一致させたいようです。その場合は単に交換してください

if (strcmp(dp->d_name, arg) != 0)

if (fnmatch(arg, dp->d_name, 0) != 0)

これにも使用できますglob。実際には、への呼び出しopendirとループが置き換えられます。使用例を次に示しglobます。

#include <glob.h>
#include <stdio.h>


static void lookup(const char *root, const char *arg)
{
    size_t n;
    glob_t res;
    char **p;

    chdir(root);
    glob(arg, 0, 0, &res);

    n = res.gl_pathc;
    if (n < 1) {
        printf("failed to find %s\n", arg);
    } else {
        for (p = res.gl_pathv; n; p++, n--) {
            printf("found %s\n", *p);
        }
    }
    globfree(&res);
}


int main(int argc, char *argv[])
{
    int i;
    for (i = 2; i < argc; i++)
        lookup(argv[1], argv[i]);
    return (0);
}
于 2012-05-21T01:59:05.257 に答える
1

あなたが何を期待しているのかわかりません。プログラムが呼び出されlookupた場合、「現在のディレクトリ」で呼び出すと、そのディレクトリにはファイルsomething.1、something.2、something.3が次のように保持されます。

lookup something*

シェルはそれをに拡張します

lookup  something.1 something.2 something.3

プログラムは3つのコマンドライン引数を認識し、readdirループで一致するものを見つけることができます。

opendir呼び出しを"/dev / shm"に変更し、元のディレクトリ(何かがあるディレクトリ[1-3])から呼び出すと、シェルは再びワイルドカードを展開しin the current directoryます。ただし、ファイルsomething.1、something.2、something.3も/ dev / shmに存在しない限り、readdirループはそれらを認識しません。

ルックアップ関数は少し奇妙であることに注意してください。私はそれがもっとこのようになることを期待します:

    static int lookup(const char * dir, const char *arg)
    {
        DIR *dirp;
        struct dirent *dp;

        if ((dirp = opendir(dir)) == NULL) {
            perror(dir);
            return -1;
        }

        while ((dp = readdir(dirp)) != NULL) {
            if (!strcmp(dp->d_name, arg)) {
                break;
            }
        }
        (void) closedir(dirp);

        printf("%s %s\n", dp ? "found" : "failed to find", arg);
        return 0;
    }
于 2012-05-21T02:42:43.093 に答える