-1

I want to be able to get the list of folders and file (if possible with sub folders) and return it (array for example)

So i have this script:

DIR *dir;
struct dirent *ent;
if ((dir = opendir ("c:\\src\\")) != NULL) {
  /* print all the files and directories within directory */
  while ((ent = readdir (dir)) != NULL) {
    printf ("%s\n", ent->d_name);  // I dont want to print, I want to add it to a array
  }
  closedir (dir);
} else {
  /* could not open directory */
  perror ("");
  return EXIT_FAILURE;
}

So i can do:

array = getFolders('.');

now if I loop thru the array i can see all folders and files.

eg:

array[0] = 'file1.txt';
array[1] = 'folder1/';
array[2] = 'folder1/file2.txt';
array[3] = 'folder1/file3.txt';
array[4] = 'folder2/';
array[5] = 'folder3/';
array[6] = 'folder3/filez.txt';

etc...

Pat R Ellery
  • 1,696
  • 3
  • 22
  • 40
  • see [scandir](http://linux.die.net/man/3/scandir) – BLUEPIXY Jul 15 '15 at 21:23
  • @BLUEPIXY will this get files as well? – Pat R Ellery Jul 15 '15 at 21:24
  • Why do you want to add it to an array? If you're just going to iterate over that array to do something with each filename, it'd be more efficient to just do it there, in the body of the `readdir()` loop. – Jonathon Reinhart Jul 15 '15 at 21:28
  • @JonathonReinhart because I will use that array multiple times in the code. I read the folder structure then I use it like 4 times ... I dont want to rescan 4 times the structure ... would you scan the /home folder every time you need something from it? – Pat R Ellery Jul 15 '15 at 21:30
  • @PatREllery There is a sample code to link destination. – BLUEPIXY Jul 15 '15 at 21:34
  • @PatREllery It depends. Do I always require an up-to-date view of the directory's contents? Or do I require that all 4 times its used it be the same. Unfortunately I don't know how you're using this information, so I can't give good advice either way. There's a use case for both approaches. – Jonathon Reinhart Jul 15 '15 at 21:47
  • Look at [ftw](http://pubs.opengroup.org/onlinepubs/009695399/functions/ftw.html) – Mark Plotnick Jul 15 '15 at 22:51
  • @MarkPlotnick and how can i return an array with ftw? – Pat R Ellery Jul 24 '15 at 16:55
  • ftw won't allow allocate and fill in an array - as the answers below show, you'll need to have some additional C code do that - but it makes recursing through subdirectories very easy. – Mark Plotnick Jul 26 '15 at 03:32

2 Answers2

0

You can allocate a list of pointers and store each entry by allocating memory for the directory entry:

char **getFolder()
{

char **list = malloc(4096* sizeof *list);
size_t i = 0;
....

  while ((ent = readdir (dir)) != NULL) {
     list[i]=strdup(ent->d_name);
     i++;
     if( i >=4096 ) { /* time to realloc */}
  }

return list;
}

and from the caller, you can use receive it as:

char **list=getFolder();

If you are going to have too many entries than you can use realloc() to increase the size of the list inside the loop. If strdup is not available, it can be easily implemented by using malloc() and strlen() functions.

I have excluded error checking for simplicity. Ideally, malloc() ans strdup should be checked for errors.

P.P
  • 117,907
  • 20
  • 175
  • 238
-1

use DIR command in popen, and malloc and realloc

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>

#define INC 1024

char **getFolders(const char *path, /* out */ size_t *count){
    char buff[1024];
    snprintf(buff, sizeof buff, "dir /B /S /ON \"%s\"", path);
    FILE *fp = popen(buff, "r");
    size_t capacity = INC;
    char **entry;
    struct stat finfo;

    if(NULL==(entry=malloc(capacity*sizeof(*entry)))){
        perror("malloc");
        exit(EXIT_FAILURE);
    }

    *count = 0;
    while(fgets(buff, sizeof buff, fp)){
        size_t len;
        for(len = 0; buff[len]; ++len){
            if(buff[len] == '\\')
                buff[len] = '/';
        }
        buff[len-1] = '\0';
        stat(buff, &finfo);
        if(S_ISDIR(finfo.st_mode))
            buff[len-1] = '/';

        entry[*count] = strdup(buff);
        if(++*count == capacity){
            capacity += INC;
            if(NULL==(entry=realloc(entry, capacity*sizeof(*entry)))){
                perror("realloc");
                exit(EXIT_FAILURE);
            }
        }
    }
    pclose(fp);
    return entry;
}

int main(void){
    size_t i, count = 0;
    char **entry = getFolders("c:/src/", &count);

    for(i = 0; i < count; ++i){
        printf("%s\n", entry[i]);
        free(entry[i]);
    }
    free(entry);
    return 0;
}
BLUEPIXY
  • 39,699
  • 7
  • 33
  • 70