2
int indent = 0;
int listDir(const char* dirname){
    DIR* dir;
    struct dirent* d;
    if(!(dir = opendir(dirname)))
        return -1;
    while((d = readdir(dir)) != NULL){
        if(strcmp(d->d_name, ".") == 0 || strcmp(d->d_name, "..") == 0 ){
            continue;
        }
        else if(d->d_type != DT_DIR){ // Any except folders.
            printf("%*s- %s:%ld\n", indent, "", d->d_name, d->d_ino);
        }
        else if(d->d_type == DT_DIR){ // Folders only
            printf("%*s[%s]\n", indent, "", d->d_name);
            char path[1024];
            snprintf(path, sizeof(path), "%s/%s", dirname, d->d_name);
            indent +=2;
            listDir(path);
            indent -=2;
        }

This function works just fine, but the only thing is that it outputs the following result as an example: Output of the above function

I need the output to be the container folder, files and then folders. The folders should be at the end of the list. For example, the above output should be:

enter image description here

einpoklum
  • 118,144
  • 57
  • 340
  • 684
nullptr
  • 127
  • 9
  • 1
    On a POSIX system, you can also use [`nftw()` to walk a directory tree](https://pubs.opengroup.org/onlinepubs/9699919799/functions/nftw.html). – Andrew Henle Jan 01 '20 at 00:48

1 Answers1

5

I'd say you have two options:

  1. Insert all of the readdir() results into a sorted data structure (or just put them in some array and sort it). And - I mean sorted in the sense of "file < directory and no other order".
  2. Read all of the entries twice - once, ignore all the subdirectories and print just the files; then use rewinddir(), then read all of the entries again, ignoring all of the regular files and only printing the subdirectories.

Option 2 is probably simpler - but with more library calls and system calls.

einpoklum
  • 118,144
  • 57
  • 340
  • 684