views:

556

answers:

7

I'm trying to figure out how to work this thing out .. For some reason, it ends at a certain point.. I'm not very good at recursion and I'm sure the problem lies somewhere there..

Also, even if I checked for cFileName != "..", it still shows up at the end, not sure why but the "." doesn't show up anymore..

void find_files( wstring wrkdir )
{
    wstring temp;

    temp = wrkdir + L"\\" + L"*"; 
    fHandle = FindFirstFile( temp.c_str(), &file_data );

    if( fHandle == INVALID_HANDLE_VALUE )
    {
         return;
    }
    else 
    { 
     while( FindNextFile( fHandle, &file_data ) ) 
     {
      if( file_data.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY &&
          wcscmp(file_data.cFileName, L".") != 0 && 
                        wcscmp(file_data.cFileName, L"..") != 0 )
      {
       find_files( wrkdir + L"\\" + file_data.cFileName  );
      }
      else if( file_data.dwFileAttributes != FILE_ATTRIBUTE_HIDDEN && 
        file_data.dwFileAttributes != FILE_ATTRIBUTE_SYSTEM  )
      {
       results << wrkdir << "\\" << file_data.cFileName << endl;
      }
     }
    }
}

After changing those, the program doesn't enumerate the remaining files left..

For example, if there is a sub folder named test, it enumerates everything inside test but doesn't finish enumerating the files inside the original directory specified.

+3  A: 

From the FindFirstFile documentation:

If the function fails or fails to locate files from the search string in the lpFileName parameter, the return value is INVALID_HANDLE_VALUE and the contents of lpFindFileData are indeterminate.

You should only exit from the one iteration not the whole program:

   if( fHandle == INVALID_HANDLE_VALUE )
   {
     return;
   }

And this may solve your other problem:

else if( file_data.dwFileAttributes != FILE_ATTRIBUTE_HIDDEN && 
   file_data.dwFileAttributes != FILE_ATTRIBUTE_SYSTEM  &&
   wcscmp(file_data.cFileName, L".") != 0 && 
   wcscmp(file_data.cFileName, L"..") != 0
 )
{
    results << wrkdir << "\\" << file_data.cFileName << endl;
}

Also see @fretje's answer as well. It gives another problem that your code has.

Updated new: You need to use fHandle as a local variable as well, not global variable.

Change to:

 HANDLE fHandle = FindFirstFile( temp.c_str(), &file_data );
Brian R. Bondy
for some reason, still won't work.. been scratching my head for hours now .. I edited the original post btw
Charles Khunt
Updated with a new problem I saw
Brian R. Bondy
+2  A: 

You are changing the value of your local wrkdir variable:

wrkdir = wrkdir + L"\\" + file_data.cFileName;
find_files( wrkdir );

I think you have to call find_files there like this:

find_files( wrkdir + L"\\" + file_data.cFileName );

and not change the value of wrkdir.

fretje
ah, nice catch :)
Brian R. Bondy
A: 

Also, check out the implementation of the CFileFind MFC class.

sean e
A: 

Personally I love the Python file and string manipulation libraries so much more than C-related libraries, maybe you can check it out sometime (it takes about 10 minutes to install python, and another 20 to get a working tutorial program running)

ryansstack
A: 

Also check out Boost Filesystem

http://www.boost.org/doc/libs/1_39_0/libs/filesystem/doc/index.htm

It rocks!

lenkite
A: 

You still have errors in your code:

  1. you ignore the results of the first search. you call FindFirstFile and handle if it fails. But if it succeeds you do not process already fetched file_data and overwrite it with FindNextFile.
  2. You don't close the search handle. Use FindClose for that.
  3. From your existing code it seems that fHandle is global - it shouldn't. It would break your recursion.

Also I think that you can resolve all the issues in your code by paying more attention to MSDN sample provided in FindFirstFile documentation.

Andrey
A: 

There are still several bugs in your code. Try this instead:

void find_files( wstring wrkdir )
{
    wstring wrkdirtemp = wrkdir;
    if( !wrkdirtemp.empty() && (wrkdirtemp[wrkdirtemp.length()-1] != L'\\')  )
    {
      wrkdirtemp += L"\\";
    }

    WIN32_FIND_DATA file_data = {0};
    HANDLE hFile = FindFirstFile( (wrkdirtemp + L"*").c_str(), &file_data );

    if( hFile == INVALID_HANDLE_VALUE )
    {
         return;
    }

    do
    {
        if( file_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
        {
            if( (wcscmp(file_data.cFileName, L".") != 0) && 
                (wcscmp(file_data.cFileName, L"..") != 0) )
            {
                find_files( wrkdirtemp + file_data.cFileName );
            }
        }
        else
        {
            if( (file_data.dwFileAttributes & (FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM)) == 0 )
            {
                results << wrkdirtemp << file_data.cFileName << endl;
            }
        }
    }
    while( FindNextFile( hFile, &file_data );

    FindClose( hFile );
}
Remy Lebeau - TeamB