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:
#include <iostream>
#include <windows.h>
#include <string>
#include <cstring>
#include <vector>
#include <stack>
#include <new>
usingnamespace 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
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?
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:
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.