2012-05-21 12 views
2

我目前正在使用最初設計爲接受參數的代碼示例,然後在當前目錄中搜索該參數,試圖使其搜索另一個目錄(/ dev/shm確切)替換「。」用「/ dev/shm」,但是當我搜索某些東西*(注意通配符)時,代碼什麼也沒有變。通配符搜索在當前目錄中工作正常,所以我不認爲這是通配符問題,如果有人能夠幫助我,儘管我會很感激,謝謝!如何獲取此readdir代碼示例以搜索其他目錄

#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); 
} 
+1

題外話:你不必在函數調用前寫'(void)'。 –

+1

@Eitan - (void)可以通過老版本的lint。OP從readdir手冊頁發佈了一個例子。和。好的代碼應該檢查每個調用的返回碼,甚至printf。 –

+0

@jimmcnamara我相信有或沒有'(void)'編譯器本質上是做同樣的事情。通過放入'(void)',你僅僅會讓你更加明顯地認爲你丟棄了返回值。我從來沒有見過這種「風格」。 –

回答

6

opendir不處理通配符。它期望一個真實的目錄路徑。我不知道你是什麼意思時,你說在當前目錄

通配符搜索工作。如果你的意思是它在你的shell,這是可以預期的。 shell將首先展開通配符,然後執行您鍵入的命令。

那麼如何解決這個問題呢?在致電opendir之前,使用glob自己擴展通配符。


編輯:對不起,我以爲你試圖匹配目錄名稱中的通配符。它看起來像你想使用通配符匹配目錄內容。在這種情況下,簡單地

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

更換

if (strcmp(dp->d_name, arg) != 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); 
} 
+0

感謝您的建議:)我已經四處尋找使用glob的一些示例/教程,但我很難找出大部分內容發生了什麼,所以我想知道如果您知道如何使用glob在任何情況下? – lacrosse1991

+0

再次感謝,有一個問題,雖然與fnmatch部分,當我使用它時,它只會顯示該文件被發現,例如說目錄包含1-a.txt 1-b.txt 1-c.txt和I搜索1 - *。txt,該程序將返回1 - *。txt被發現,而不是1-a.txt 1-b.txt 1-c.txt被發現,儘管我不確定我是否可能會丟失東西 – lacrosse1991

+0

首先,模式中必須有一個通配符,但我認爲這只是一個複製粘貼問題:)檢查循環中的邏輯。如果沒有匹配('fnmatch'或'strcmp'返回非零),則轉到目錄中的下一個元素。如果有匹配,則打印並退出。將退出部分移出循環,並且您已全部完成設置。 –

1

我不知道你期待什麼。如果你的程序被稱爲lookup然後如果你把它在「當前目錄」,其中該目錄保存文件something.1,something.2和something.3這樣的:

lookup something* 

外殼將其擴大到

lookup something.1 something.2 something.3 

並且您的程序將看到三個命令行參數,並且將能夠在readdir循環中找到一個匹配項。

如果您將opendir調用更改爲「/ dev/shm」,並從原始目錄(具有某些內容[1-3])中調用它,那麼shell將再次擴展通配符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; 
    } 
相關問題