C中的递归子目录处理

时间:2014-03-08 23:37:20

标签: c file recursion directory dirent.h

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

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

    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 个答案:

答案 0 :(得分:0)

未显示函数声明,但它可能类似于

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);