树的遍历有一个应用,便是目录的枚举。本程序实现了一个类似 tree 命令的功能,便于日后编程时参考。

#include <iostream>
#include <string>
#include <windows.h>

/*
 * @brief: Print name of files in a recursive way.
 * @param: path, initial traversed path
 * @param: depth, which value is decisive to the indentation when printing
 * @param: b_print_file, only print directories' name when it was set to false
 */
void  print_directory(const std::wstring  &path, size_t depth, bool  b_print_files = false)
{
    WIN32_FIND_DATA  st_find_data;
    HANDLE  h_directory = FindFirstFile((path + L"\\*").c_str(), &st_find_data);

    if (INVALID_HANDLE_VALUE != h_directory)
    {
        if (depth == 1)
        {
            std::wcout << path << std::endl;
        }
        do
        {
            if (wcscmp(st_find_data.cFileName, L".") == 0 || wcscmp(st_find_data.cFileName, L"..") == 0)
            {
                continue;
            }
            // Recursive traversal when encountering subdirectories. 
            if ((st_find_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0)
            {
                for (size_t i = 0; i < depth; ++i)
                {
                    std::wcout << "-";
                }
                std::wcout << st_find_data.cFileName << std::endl;
                print_directory(std::wstring(path) + L"\\" + st_find_data.cFileName, depth + 1, b_print_files);
                std::wcout << std::endl;
            }
            else if (b_print_files)
            {
                std::wcout << " |";
                for (size_t i = 0; i < depth * 2; ++i)
                {
                    std::wcout << " ";
                }
                std::wcout << " " << st_find_data.cFileName << std::endl;
            }
        } while (FindNextFile(h_directory, &st_find_data));
    }
    // According to https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-findfirstfilea
    // When the search handle is no longer needed, close it by using the FindClose function, not CloseHandle.
    // CloseHandle(h_directory);
    FindClose(h_directory);
}