【问题标题】:Recursive sub-directory processing in CC中的递归子目录处理
【发布时间】:2014-04-12 03:51:00
【问题描述】:

好的,所以我正在尝试处理目录列表和其中的文件。 到目前为止,我的程序运行良好,除了碰巧超过 给定目录中的 1 个子目录。我绝对无法弄清楚为什么会发生这种情况。

以下是我正在使用的相关代码的 sn-ps。任何帮助将不胜感激。

    int i=0;
    int subcount=0;
    char temp[256];
    struct dirent *directory;
    DIR *pdirectory;
    struct stat fileinfo;

    chdir(path);
    pdirectory=opendir(path);
    if (pdirectory==NULL)
    {
            perror(path);
            exit(EXIT_FAILURE);
    }
    printf("%s\n",path);
    while ((directory=readdir(pdirectory)) != NULL)
    {

         if (!stat(directory->d_name,&fileinfo))
        {

            if(!strcmp(directory->d_name,"."))
            continue;
            if(!strcmp(directory->d_name,".."))
            continue;   

         if (S_ISDIR(fileinfo.st_mode) && (!S_ISREG(fileinfo.st_mode)))
         {
            (char*)directory->d_name;
            strcpy(temp,directory->d_name);
            printf("Dir Name: %s\n",temp);
            subcount=subcount+1;
            printf("Sub Count: %d\n",subcount);


            for (i=0; i < subcount; i++)
            { 
              strcat(path,"/");
              strcat(path,temp);           
              processDir(path); //Recursive Call to Function

            } 
             closedir(pdirectory);
            }  

【问题讨论】:

  • 它不起作用 描述性不是很好。到底发生了什么?
  • 好的,所以我有一个父文件夹,其中包含 1 个名为 Test 的子目录。在 Test 中,有 2 个名为 Test 1 和 Test2 的子目录。我的程序处理父文件夹、Test 和 Test2 中的所有文件,但由于某种原因似乎跳过了 Test1。
  • 如果您发布 SCCE:一个独立的可编译示例,您通常只会得到有关无法正常工作的问题的答案。在这种情况下,提取目录遍历代码。
  • 您在最后一个 for 循环内多次附加到 path,这使得第一次迭代后路径无效。

标签: c file recursion directory dirent.h


【解决方案1】:

函数声明没有显示,但它可能看起来像

void processDir(char *path);

不应假定path 有空间用于附加附加的char,不幸的是,

会发生这种情况
strcat(path,"/");
strcat(path, temp);           

此外,如果有另一个子目录,path 不会恢复,而 next 子目录名称会被附加 (@doukremt)。相反,请使用工作区buffer。顺便说一句:不需要temp

char buffer[1024];
sprintf(buffer, "%s/%s", path, directory->d_name);
processDir(buffer); //Recursive Call to Function

稍后:
您想使用snprintf() 来确保缓冲区不会溢出并采取规避措施。
简化:int len = sprintf(buffer, "%s/", path); 在循环之前然后简单地:

strcpy(&buffer[len], directory->d_name);
processDir(buffer); //Recursive Call to Function

再次添加防止/检测缓冲区溢出代码。


可选方法:如果 C99 或更高版本,请使用 VLA

char buffer[strlen(path) + 1 + sizeof(directory->d_name) + 1];

或使用动态内存分配。

size_t size = strlen(path) + 1 + sizeof(directory->d_name) + 1;
char *buffer = malloc(size);  // TDB add NULL check
len = sprintf(buffer, "%s/", path);`
while ((directory=readdir(pdirectory)) != NULL) {
  ...
  strcpy(&buffer[len], directory->d_name);
  processDir(buffer);
  ...
}
free(buffer);

【讨论】:

    猜你喜欢
    • 2015-10-23
    • 1970-01-01
    • 2013-08-28
    • 1970-01-01
    • 2012-11-23
    • 2011-06-22
    • 1970-01-01
    • 2017-03-26
    • 1970-01-01
    相关资源
    最近更新 更多