Directory tree

I am trying to make a directory tree with windows.h. The program gets stuck in an infinite loop and I haven't the slightest idea why. Here is the full code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#include <iostream>
#include <windows.h>
#include <string>
#include <cstring>
#include <vector>
#include <stack>
#include <new>

using namespace std;

//declaring handle and find_data struct
HANDLE h;
WIN32_FIND_DATA fd;
stack <HANDLE> hstack;
stack <WIN32_FIND_DATA> fdstack;

struct node
{
    string value;
    vector <node *> subnodes;
};  //end node

void createtree(node * a, string dir)
{
    if (a != 0)
    {
        a->value = dir; //Store dir to a->value
        cout << a->value << endl;
        h = FindFirstFile((a->value+"/*.").c_str(), &fd);    //Initialize the handle to FindFirstFile((a->value+"/*.").c_str(), &fd)
        //insure that the "." and ".." folders won't be brought into the tree
        while ((((string)fd.cFileName == ".") || ((string)fd.cFileName == "..")) && FindNextFile(h, &fd))
        {
            //do nothing; FindNextFile(h,&fd) is changing fd.cFileName to a new folder
        }   //end while
        if (((string)fd.cFileName != ".") && ((string)fd.cFileName != ".."))    //if there are still folders to search
        {
            hstack.push(h);  //Push h into the stack
            fdstack.push(fd);   //push the fd struct into the stack
            do
            {
                dir = a->value + '/' + (string)((fdstack.top()).cFileName); //store found directory to dir
                a->subnodes.push_back(new(nothrow)node);    //push a new node into the subnodes vector
                createtree(a->subnodes.back(), dir);    //call this function with this new node as the first parameter
                cout << "a->subnodes.size() == " << a->subnodes.size()<< endl;
            }   //end do
            while (FindNextFile(hstack.top(),&(fdstack.top())));
            hstack.pop();
            fdstack.pop();
        }   //end if
        else    //There is only the "." and ".." folders.
        {
            hstack.pop();   //pop handle from stack
            fdstack.pop();
            a->subnodes.push_back(0);   //(optional) push 0 into a->subnodes
            createtree(a->subnodes[0], dir);
        }   //end else
    }   //end if
    else
    {
        cout << "I took a null pointer value."<<endl;
    }   //end else
}   //end createtree

int main()
{
    node tree;
    createtree(&tree,"C:/Users/miwarren/Desktop");
    return 0;
}   //end main 

Originally, I had my createtree() look like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
void createtree(node * a, string dir)
{
    if (a != 0)
    {
        a->value = dir; //Store dir to a->value
        cout << a->value << endl;
        h = FindFirstFile((a->value+"/*.").c_str(), &fd);    //Initialize the handle to FindFirstFile((a->value+"/*.").c_str(), &fd)
        //insure that the "." and ".." folders won't be brought into the tree
        while ((((string)fd.cFileName == ".") || ((string)fd.cFileName == "..")) && FindNextFile(h, &fd))
        {
            //do nothing; FindNextFile(h,&fd) is changing fd.cFileName to a new folder
        }   //end while
        if (((string)fd.cFileName != ".") && ((string)fd.cFileName != ".."))    //if there are still folders to search
        {
            do
            {
                dir = a->value + '/' + (string)fd.cFileName; //store found directory to dir
                a->subnodes.push_back(new(nothrow)node);    //push a new node into the subnodes vector
                createtree(a->subnodes.back(), dir);    //call this function with this new node as the first parameter
                cout << "a->subnodes.size() == " << a->subnodes.size()<< endl;
            }   //end do
            while (FindNextFile(h,&fd));
        }   //end if
    }   //end if
}   //end createtree 

but then I realized that createtree() wouldn't be accessing all the subfolders of Desktop because BOTH h AND fd CHANGE WITH THE RECURSIVE CALL. So, I decided to store the h's and fd's to their respective stacks and just use the stacks to get the data. I popped both the hstack and fdstack when I was done (right after the do-while loop) and it still throws the same error. (In fact, it simply runs forever until either I or the operating system intervene.) Why is it doing this?
Last edited on
EDIT: I think I have found the reason why it's doing this: I am popping both the hstack and the fdstack whenever there are no folders found. That's fine and dandy when the leaf directory has a parent directory whose parent directory has only that directory, but what happens when there "grandparent-directory" has only multiple subdirectories (including the one you have successfully traversed)?
For example: the code works fine for situations like:
1
2
a->subnodes[0]->value == a->value + '/' + "something";
a->subnodes[0]->subnodes[0].value == a->subnodes[0]->value + '/' + "another folder";

but how to handle cases like:
1
2
a->subnodes[0]->value == a->value + '/' + "something";
a->subnodes[1]->value == a->value + '/' + "some other stuff";
?
I try removing the
1
2
hstack.pop();
fdstack.pop();

from the else statement, but that is where the problems begin: I am on school computer, so I have Code::Blocks folder on the Desktop, too. It gets stuck in infinite loop when it hits a file that has no extension; it came up in hstack.top(). How would you prevent such files from being found? There ought to be a way to test to see if the thing that was found is actually a file.
Last edited on
EDIT: I found out that you could just use (fdstack.top()).dwFileAttributes Link here: http://msdn.microsoft.com/en-us/library/aa365740%28VS.85%29.aspx Data problem solved, which means the program this is for is as good as written!
Last edited on
Topic archived. No new replies allowed.