2016-02-28 81 views
1

我不知道爲什麼,但我沒有找到問題所在。我運行一個測試來查看它是一個目錄還是一個文件,甚至文件被視爲文件夾。C - 遞歸複製文件

的問題是,當運行循環,即使是文件它進入目錄的過程和postrs「文件1的目錄」

這裏是代碼:

void copie_dossier(char *doss1, char *doss2) { 
    struct dirent *dptr; 
    DIR *dp; 
    struct stat stbuf; 

    char newDest[strlen(doss2) + 1]; 
    char tempSrc[strlen(doss1) + 1]; 
    strcat(doss2, "/"); 
    strcat(doss1, "/"); 
    strcpy(newDest, doss2); 
    strcpy(tempSrc, doss1); 

    stat(doss1, &stbuf); 

    dp = opendir(doss1); 

    /* 
    if (!dp) { 
     perror("open_dir"); 
     exit(1); 
    } 
    */ 

    if (!(dp)) 
     return; 
    if (!(dptr = readdir(dp))) 
     return; 

    int mk = mkdir(doss2, 0777); 
    if (mk == -1) { 
     perror("create_dir"); 
     exit(1); 
    } 

    while ((dptr = readdir(dp)) != NULL) { 
     struct stat stbuf2; 
     //stat(dptr->d_name, &stbuf2); 
     char *new = dptr->d_name; 

     if (!strcmp(dptr->d_name, ".") || !strcmp(dptr->d_name, "..")) { 
      continue; 
     } 

     if (!stat(tempSrc, &stbuf2)) { 
      if (S_ISREG(stbuf.st_mode)) { 
       printf("%s for files\n", dptr->d_name); 
       strcat(newDest, dptr->d_name); 
       strcat(tempSrc, dptr->d_name); 
       copy_files(tempSrc, newDest); 
       strcpy(newDest, doss2); 
       strcpy(tempSrc, doss1); 
      } 

      if (S_ISDIR(stbuf.st_mode)) { 
       printf("%s for directory \n", dptr->d_name); 
       strcat(newDest, dptr->d_name); 
       strcat(tempSrc, dptr->d_name); 
       copie_dossier(tempSrc, newDest); 
       strcpy(newDest, doss2); 
       strcpy(tempSrc, doss1); 
      } 
     } 
    } 
    closedir(dp); 
} 
+1

你的錯誤信息是什麼? – zx485

+0

請搜索一下。關於如何遞歸地在本網站上單獨輸入目錄的例子有數以千計的例子,更不用說整個互聯網,其中可能有數百萬例子。 –

+0

基本上代碼運行良好......但測試認爲文件是文件夾,所以它沒有做什麼與他們 – Ch1234

回答

1

的問題是在本地緩存的配置:

char newDest[strlen(doss2) + 1]; 
char tempSrc[strlen(doss1) + 1]; 
strcat(doss2, "/"); 
strcat(doss1, "/"); 
strcpy(newDest, doss2); 
strcpy(tempSrc, doss1); 

即使是第一個使用newDesttempSrc調用未定義的行爲,你ç opy字符串,不適合目的地。 newDesttempSrc分別準確分配doss1doss2(最終'\0')中的字符數,但在複製之前附加一個額外的/

後面的代碼中,您將連接目錄條目名稱,導致進一步未定義的行爲。

您必須更改路徑名組合的邏輯。您可以使用內存分配或全局緩衝區,在該緩衝區中連接條目,同時記住用於結束將路徑名刪除回到先前狀態的路徑名。

在測試目錄/文件名時存在另一個大問題:您不需要stat()正確的路徑名,而使用單獨的stbuf2而不是stbuf。您應該首先創建當前條目的路徑名,將其傳遞到stat()並檢查生成的stbuf上的目錄和文件名。

這裏是一個改進版本:

char *make_path(const char *path, const char *name) { 
    size_t len = strlen(path); 
    char *p = malloc(len + 1 + strlen(name) + 1); 
    if (p) { 
     strcpy(p, path); 
     p[len] = '/'; 
     strcpy(p + len + 1, name); 
    } 
    return p; 
} 

void copie_dossier(const char *doss1, const char *doss2) { 
    DIR *dp; 
    struct dirent *dptr; 

    dp = opendir(doss1); 
    if (dp == NULL) 
     return; 

    int mk = mkdir(doss2, 0777); 
    if (mk == -1) { 
     perror("create_dir"); 
     exit(1); 
    } 

    while ((dptr = readdir(dp)) != NULL) { 
     struct stat stbuf; 
     char *source, *dest; 

     if (!strcmp(dptr->d_name, ".") || !strcmp(dptr->d_name, "..")) { 
      continue; 
     } 

     source = makepath(doss1, dptr->d_name); 
     dest = makepath(doss2, dptr->d_name); 
     if (!source || !dest) { 
      perror("makepath"); 
      exit(1); 
     }     
     if (!stat(source, &stbuf)) { 
      if (S_ISREG(stbuf.st_mode)) { 
       printf("%s for files\n", dptr->d_name); 
       copy_files(source, dest); 
      } else 
      if (S_ISDIR(stbuf.st_mode)) { 
       printf("%s for directory \n", dptr->d_name); 
       copie_dossier(source, dest); 
      } 
     } else { 
      // should issue a diagnostic message 
     } 
     free(source); 
     free(dest); 
    } 
    closedir(dp); 
} 

你沒有張貼代碼功能copy_files。我假設它複製一個文件,儘管名稱。

+0

嘿,非常感謝。我使用的代碼主要只用於目錄明顯,這就是爲什麼它無法識別該文件,因爲我總是在最後添加'/'。感謝您的幫助,我也會更仔細地使用代碼格式。 – Ch1234

+0

@ K.Xhel:閱讀並研究我的答案,代碼以幾種不同的方式被破解。 – chqrlie