开发者

Unix c program to list directories recursively

开发者 https://www.devze.com 2023-03-27 08:06 出处:网络
I am working on a POSIX C learning exercise that involves recursively listing files/folders in a specified directory. The program takes in as arguments of one or more directories. I can list the conte

I am working on a POSIX C learning exercise that involves recursively listing files/folders in a specified directory. The program takes in as arguments of one or more directories. I can list the contents of the initial directory fine but having a problem with the recursion. Is something wrong with the way I am passing in the argument for the recursive function call?

#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <dirent.h>
#include <errno.h>
#include <string.h>

void listdir(char *argv[])
{
  DIR *mydirhandle;

  struct dirent *mydirent;

  struct stat statinfo;

  int n = 1;

  while(argv[n] != NULL)
  {
    if((mydirhandle = opendir(argv[n])) == NULL)
    {
      perror("opendir");
      exit(1);
    }

    printf("%s/\n", argv[n]);

    while((mydirent = readdir(mydirhandle)) != NULL)
    { 
      if((strcmp(mydirent->d_name, ".") == 0) || (strcmp(myd开发者_运维问答irent->d_name, "..") == 0))

      {
        continue;
      }

      else           
      {
        printf("\t%s\n", mydirent->d_name);

         //check if next entry is a directory       
         if(mydirent->d_type == DT_DIR)
        {   
             //is current directory being passed correctly here?
            listdir(mydirent->d_name);
        }
      }        
    }                       
    n++;
    closedir(mydirhandle);
  }
}
int main(int argc, char *argv[])
{
  if(argc < 2)
  {
    printf("usage: %s <directory>\n", argv[0]);
    return 0;
  }

  listdir(argv);
  return 0;
}


The d_name member of struct dirent is the basename of the item in question. So, if you're going through a directory like this:

.
..
where-is/
   pancakes/
       .
       ..
       house

Once you're in where-is, you'll try to listdir("pancakes") but that won't work because you need to listdir("where-is/pancakes").

You need to combine that with the name of the directory that you're looking before you have something that you can pass to the next listdir call.

You'll want to replace things like this:

listdir(mydirent->d_name);

with things like this:

char *next_dir = malloc(strlen(argv[n]) + strlen(mydirent->d_name) + 1 + 1);
sprintf(next_dir, "%s/%s", argv[n], mydirent->d_name);
listdir(next_dir);
free(next_dir);

Alternatively, you could chdir into the directories as you enter them and then chdir back up when you're done.


Turning on warnings will show that you're passing the wrong type when making the recursive function call. I would simply make listdir take a char * argument rather than char **, and then use a for loop in main to loop over multiple arguments if you need to.


You should use ftw for this, it calls a given callback on every item of the subtree. This way, you avoid using explicit recursion yourself, and your code will get much shorter.

0

精彩评论

暂无评论...
验证码 换一张
取 消