2013-10-17 79 views
1

我無法正確編寫此功能。它應遞歸列出第一個參數提供的路徑(如ls -R)的內容,但它會過早停止。下面是代碼,預期輸出和輸出我得到:遞歸列表目錄

使用
int browseDir (const char *path, const int *options) 
{ 
    char callingdir[MAXDIRLEN]; 
    char currentdir[MAXDIRLEN]; 

    getcwd(callingdir,MAXDIRLEN); 

    DIR *dirstream; 
    struct dirent *dir_entry; 
    struct stat file_data; 
    LIST subd_list = newList(); 

    if (path == NULL) 
     strcpy(currentdir,callingdir); 
    else 
     strcpy(currentdir,path); 

    dirstream = opendir(currentdir); 
    printf("Listing: %s\n",currentdir); 
    chdir(currentdir); 

    if (dirstream == NULL) 
    { 
     perror("Error: cannot open directory\n"); 
     return 0; 
    } 

    while((dir_entry = readdir(dirstream)) != NULL) 
    { 
     if (!ISSET_A_FLAG(*options)) 
     { 
      if (dir_entry->d_name[0]=='.') 
       continue; 
     } 
     if (!ISSET_S_FLAG(*options)) 
     { 
      stat(dir_entry->d_name, &file_data); 
      printStat(&file_data); 
     } 
     printf("%s ",dir_entry->d_name); 
     printf("\n"); 
     if (ISSET_R_FLAG(*options) && (dir_entry->d_type & DT_DIR) && strcmp(dir_entry->d_name,".") && strcmp(dir_entry->d_name,"..")) 
      addNode(subd_list, dir_entry->d_name); 
    } 
    closedir(dirstream); 

    while(!isEmpty(subd_list)) 
    { 
     browseDir((*subd_list)->data, options); 
     delNode(subd_list); 
    } 

    chdir(callingdir); 
    return 0; 
} 

輸出LS -Rli(預期)

[email protected]:~/Dropbox/programming/SO/myshell2$ ls -lRi /home/tod/programming/shelldeb 
/home/tod/programming/shelldeb: 
totale 52 
1150597 drwxr-xr-x 3 tod tod 4096 ott 18 02:34 bin 
1054396 -rw-rw-r-- 1 tod tod 7696 ott 18 15:21 commands.c 
1045205 -rw-rw-r-- 1 tod tod 1233 ott 16 23:14 commands.h 
1045208 -rw-rw-r-- 1 tod tod 952 ott 18 17:10 list.c 
1057517 -rw-rw-r-- 1 tod tod 244 ott 18 15:22 list.h 
1055205 -rw-r--r-- 1 tod tod 487 ott 18 02:36 main.c 
1150595 drwxr-xr-x 3 tod tod 4096 ott 18 02:34 obj 
1057590 -rw-rw-r-- 1 tod tod 1213 ott 18 09:33 parsing.c 
1057622 -rw-rw-r-- 1 tod tod 193 ott 18 09:33 parsing.h 
1055154 -rw-rw-r-- 1 tod tod 1368 ott 18 02:51 shelldeb.cbp 
1057688 -rw-rw-r-- 1 tod tod 665 ott 18 15:22 shelldeb.depend 
1057721 -rw-rw-r-- 1 tod tod 1413 ott 18 23:20 shelldeb.layout 

/home/tod/programming/shelldeb/bin: 
totale 4 
1150598 drwxr-xr-x 3 tod tod 4096 ott 20 14:02 Debug 

/home/tod/programming/shelldeb/bin/Debug: 
totale 4 
1150684 drwxrwxr-x 4 tod tod 4096 ott 20 14:02 r55 

/home/tod/programming/shelldeb/bin/Debug/r55: 
totale 8 
1150685 drwxrwxr-x 2 tod tod 4096 ott 20 14:03 tmpfolder 
1150686 drwxrwxr-x 2 tod tod 4096 ott 20 14:02 tmpfolder2 

/home/tod/programming/shelldeb/bin/Debug/r55/tmpfolder: 
totale 0 
1045360 -rw-rw-r-- 1 tod tod 0 ott 20 14:03 myfile 

/home/tod/programming/shelldeb/bin/Debug/r55/tmpfolder2: 
totale 0 

/home/tod/programming/shelldeb/obj: 
totale 4 
1150596 drwxr-xr-x 3 tod tod 4096 ott 20 14:01 Debug 

/home/tod/programming/shelldeb/obj/Debug: 
totale 20 
1046334 -rw-rw-r-- 1 tod tod 15088 ott 18 17:10 commands.o 
1046232 -rw-rw-r-- 1 tod tod  0 ott 20 14:01 comment.txt 
1150683 drwxrwxr-x 2 tod tod 4096 ott 20 14:02 tmpfolder 

/home/tod/programming/shelldeb/obj/Debug/tmpfolder: 

電流輸出運行我的shell:

> list /home/tod/programming/shelldeb -r 
Listing: /home/tod/programming/shelldeb 
1057517 -rw-rw-r-- 1 1000 1000  244 list.h 
1054396 -rw-rw-r-- 1 1000 1000  7696 commands.c 
1057590 -rw-rw-r-- 1 1000 1000  1213 parsing.c 
1150597 drwxr-xr-x 3 1000 1000  4096 bin 
1045208 -rw-rw-r-- 1 1000 1000  952 list.c 
1055154 -rw-rw-r-- 1 1000 1000  1368 shelldeb.cbp 
1150595 drwxr-xr-x 3 1000 1000  4096 obj 
1045205 -rw-rw-r-- 1 1000 1000  1233 commands.h 
1057688 -rw-rw-r-- 1 1000 1000  665 shelldeb.depend 
1057721 -rw-rw-r-- 1 1000 1000  1413 shelldeb.layout 
1057622 -rw-rw-r-- 1 1000 1000  193 parsing.h 
1055205 -rw-r--r-- 1 1000 1000  487 main.c 
Listing: obj 
1150596 drwxr-xr-x 3 1000 1000  4096 Debug 
Listing: Debug 
1046232 -rw-rw-r-- 1 1000 1000  0 comment.txt 
1150683 drwxrwxr-x 2 1000 1000  4096 tmpfolder 
1046334 -rw-rw-r-- 1 1000 1000 15088 commands.o 
Listing: tmpfolder 
1054413 -rw-rw-r-- 1 1000 1000  0 tmp.txt 
+6

歡迎來到Stack Overflow!在不知道代碼出錯的情況下,提供有關如何調試的建議要困難得多。如果你編輯你的問題以包含你得到的輸出,並且詳細描述它與你打算的不同之處,你會很有可能得到一個有用的答案。 –

+0

感謝您的好意,我使用新信息編輯代碼(因爲我已經改進了一些代碼),並且還會添加輸出。 –

+0

嘗試添加一些調試printf()到您的代碼 - 例如。在遞歸函數的入口處,也許在每次調用browseDir後列出'subd_list',這樣就可以看出它爲什麼會提前終止。 – willus

回答

0

如果你需要一個像ls這樣的程序(只需要目錄路徑,因爲它只是參數),那麼我認爲你太過複雜了,這是我的版本:

struct dirent *file = NULL; 
DIR * direc = NULL; 

if((direc = opendir(argv[1])) == NULL) 
{ 
     perror(""); 
     exit(-1); 
} 
while((file = readdir(direc)) != NULL) 
     printf("%s" , file->d_name); 

和你有它一個基本的工作ls像程序

+0

謝謝你的回答。不幸的是,我的目標是編寫一個完整的基本shell,包含ls(在本例中稱爲列表)命令。問題只在於我沒有成功實現遞歸列表列表-r,它應該像ls -R一樣工作。 –

1

我終於在一個非常簡單的方法寫一個遞歸列表功能。我在c標準庫中找到了函數nftw(),基本上它完成了所有的工作。 這裏是誰也感興趣的代碼:),打印的目錄項的相關信息

static int list (const char *path) 
{ 
    char calling_dir[MAXDIRLEN]; 
    DIR *dirstream; 
    struct dirent *dir_entry; 
    struct stat file_data; 

    getcwd(calling_dir,MAXDIRLEN); 
    dirstream=opendir(path); 

    if (dirstream == NULL) 
    { 
     perror("Error: cannot open directory\n"); 
     return -1; 
    } 
    chdir(path); 

    while((dir_entry = readdir(dirstream)) != NULL) 
    { 
     if (!ISSET_A_FLAG(options)) 
    { 
     if (dir_entry->d_name[0]=='.') 
     continue; 
    } 
     if (!ISSET_S_FLAG(options)) 
    { 
     stat(dir_entry->d_name, &file_data); 
     printStat(&file_data); 
    } 
     printf("%s ",dir_entry->d_name); 
     printf("\n"); 
    } 
    closedir(dirstream); 
    chdir(calling_dir); 
    return 0; 
} 

static int list_R (const char *entry_path, const struct stat *entry_stat,int typeflag,struct FTW *ftwbuf) 
{ 
    int status; 
    if(typeflag & FTW_D) 
    { 
     printf("\nContent of %s : \n",entry_path); 
     status=list(entry_path); 
    } 
    if (status == -1) 
    return status; 
    return 0; 
} 

與這兩個功能,你只需要執行printstat(。 簡單調用nftw(path,list_R,1,ftw_flags);在設置FTW_PHYS標誌後執行作業。