How do I get the tree structure of a filesystem?

Question:

You need to get a list of files in directories and subdirectories in the following form:

A\B\1
A\B\2
A\B\C\1
A\B\C\2
A\B\C\3
A\B\C\D\1
A\B\C\D\2
A\E\1
A\E\2
...

It is clear that you need to use recursion. That's what I did:

#include <windows.h>
#include <stdio.h>
#include <stdbool.h>
#include <wchar.h>
#include <stdlib.h>

struct Tree {
    bool is_folder;
    wchar_t data[256];
    unsigned children_num;
    struct Tree* parent;
    struct Tree* children[1024];
};

void create_tree(struct Tree* node);

int main() {
    struct Tree Root = {
        .is_folder = true,
        .data = L"C:\\Users\\user\\Music",
        .parent = NULL,
        .children_num = 0
    };

    create_tree(&Root);

    return 0;
}

void create_tree(struct Tree* Root) {
    WIN32_FIND_DATAW find_file_data;
    HANDLE file_handel;

    /* Файлы и директории ищутся по маске. Т.е. мы находим все
       файлы подходящие под маску "C:\\Users\\user\\Music\\*". */
    wchar_t patch[258];
    wcscpy(patch, Root->data);
    wcscat(patch, L"\\*");

    file_handel = FindFirstFileW(patch, &find_file_data);
    if (file_handel != INVALID_HANDLE_VALUE) {
        do {
            /* "." - текущая директория, ".." - директория уровнем выше. */ 
            if (!wcscmp(find_file_data.cFileName, L".") ||
                !wcscmp(find_file_data.cFileName, L"..")) {
                continue;
            }

            struct Tree* node = malloc(sizeof(*node));
            node->children_num = 0;
            /* Записываем имя элемента. */
            wcscpy(node->data, find_file_data.cFileName);

            /* Мы нашли директорию. */
            if ((find_file_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
                node->is_folder = true;
                /* По-идее, так как в этой директории могут быть свои файлы и подпапки,
                   нужно обработать и их. */
                create_tree(node);
            } else {
                node->is_folder = false;
            }

            wprintf(L"%s\\%s%s", Root->data, node->data, node->is_folder ? L"\\\n" : L"\n");

            /* Добавляем елемент в дерево. */
            Root->children[Root->children_num] = node;
            Root->children_num++;
        } while (FindNextFileW(file_handel, &find_file_data));

        FindClose(file_handel);
    }
}

Here is the output of the program:

C:\Users\user\Music\1.txt                                         
C:\Users\user\Music\25-17\                                        
C:\Users\user\Music\2Pac\                                         
C:\Users\user\Music\5'nizza\                                      
C:\Users\user\Music\50 Cent\                                      
C:\Users\user\Music\ACDC\                                         
C:\Users\user\Music\Avicii\                                       
C:\Users\user\Music\Beatles\                                      
C:\Users\user\Music\CENTER\                                       
C:\Users\user\Music\Chuck Berry\                                  
C:\Users\user\Music\Classic\                                      
C:\Users\user\Music\Covers\                                       
C:\Users\user\Music\Cranberries\                                  
C:\Users\user\Music\Crash Test Dummies\                           
C:\Users\user\Music\Dash\                                         
C:\Users\user\Music\David Bowie\                                  
C:\Users\user\Music\desktop.ini                                   
C:\Users\user\Music\Eminem\                                       
C:\Users\user\Music\Imagine Dragons\                              
C:\Users\user\Music\John Lenon\                                   
C:\Users\user\Music\Kellee Maize\                                 
C:\Users\user\Music\KISS\                                         
C:\Users\user\Music\Kongos\                                       
C:\Users\user\Music\Lil Peep\                                     
C:\Users\user\Music\Lil Pump\                                     
C:\Users\user\Music\Linkin Park\                                  
C:\Users\user\Music\Metallica\                                    
C:\Users\user\Music\MS MR\                                        
C:\Users\user\Music\Nautilus Pompilus\                            
C:\Users\user\Music\Nirvana\                                      
C:\Users\user\Music\Noize MC\                                     
C:\Users\user\Music\Old Gods of Asgard\                           
C:\Users\user\Music\One Rupublic\                                 
C:\Users\user\Music\Other\                                        
C:\Users\user\Music\Oxxxymiron\                                   
C:\Users\user\Music\Pink Floyd\                                   
C:\Users\user\Music\Poets of the Fall\                            
C:\Users\user\Music\Post Malone\                                  
C:\Users\user\Music\Radiohead\                                    
C:\Users\user\Music\Roy Jones Jr\                                 
C:\Users\user\Music\Soundtracks\                                  
C:\Users\user\Music\Sting\                                        
C:\Users\user\Music\The Animals\                                  
C:\Users\user\Music\The Lonely Biscuits\                          
C:\Users\user\Music\The Shins\                                    
C:\Users\user\Music\The Wanted\                                   
C:\Users\user\Music\Three Days Grace\                             
C:\Users\user\Music\Twenty One Pilots\                            
C:\Users\user\Music\VLNY\                                         
C:\Users\user\Music\Yong Jeezy\                                   
C:\Users\user\Music\Zayde Wolf\                                   

As you can see, only the first level directories and files are displayed. In this regard, a couple of questions:

  1. Is the algorithm written correctly?
  2. If so, why is the program not working correctly?
  3. Is there a better way to accomplish this task?

Answer:

In your node->data , as I understand it, there is only the file name, without the path to it. And when you call create_tree recursively, then at the entrance to Root->data sees only the file name and, of course, cannot find anything.

In node->data you need to put the full path from the root.

– Mike

Scroll to Top
AllEscort