We help IT Professionals succeed at work.

Using Visual C++, how can I retrieve the sub-folders and filenames in a folder, which has space in it's name? It should also work in Vista.

1,349 Views
Last Modified: 2013-11-26
Hi,

I'm trying to list all sub-folders and file names in a directory and I thought it was working till it was tested in Vista. I found out that in Vista if the folder name had a space in it the code i have doesn't work. I'm programming using Visual C++ and using functions from io.h.... I'm attaching the code with this. Any help will be much appreciated.
...
			struct _finddata_t c_file;
			long hFile;
			
			if( (hFile = (long)_findfirst( szPathPattern.c_str(), &c_file )) == -1L)
			{
				// Nothing in directory
				return;
			}
			else
			{
				szName = string(c_file.name);
				if (c_file.attrib & _A_SUBDIR)
					szName = BRACKET_OPEN + szName + BRACKET_CLOSED;
	
				// Add it to the listbox if it passes the filter
				if (_matchItem(szName))
					_mLbxFiles->addItem(new MyListItem(szName));
			}
 
			// Get the other ones
			while( _findnext( hFile, &c_file ) == 0 )
			{
				szName = string(c_file.name);
				if (c_file.attrib & _A_SUBDIR)
					szName = BRACKET_OPEN + szName + BRACKET_CLOSED;
 
				// Add it to the listbox if it passes the filter
				if (_matchItem(szName))
					_mLbxFiles->addItem(new MyListItem(szName));
			}
			
			_findclose( hFile );
...

Open in new window

Comment
Watch Question

jkr
CERTIFIED EXPERT
Top Expert 2012

Commented:
You might want to use the Windows APIs for that purpose, see http://msdn.microsoft.com/en-us/library/aa365200.aspx ("Listing the Files in a Directory"):
#include <windows.h>
#include <tchar.h> 
#include <stdio.h>
#include <strsafe.h>
 
void ErrorHandler(LPTSTR lpszFunction);
 
int _tmain(int argc, TCHAR *argv[])
{
   WIN32_FIND_DATA ffd;
   LARGE_INTEGER filesize;
   TCHAR szDir[MAX_PATH];
   size_t length_of_arg;
   HANDLE hFind = INVALID_HANDLE_VALUE;
   DWORD dwError=0;
   
   // If the directory is not specified as a command-line argument,
   // print usage.
 
   if(argc != 2)
   {
      _tprintf(TEXT("\nUsage: %s <directory name>\n"), argv[0]);
      return (-1);
   }
 
   // Check that the input path plus 2 is not longer than MAX_PATH.
 
   StringCchLength(argv[1], MAX_PATH, &length_of_arg);
 
   if (length_of_arg > (MAX_PATH - 2))
   {
      _tprintf(TEXT("\nDirectory path is too long.\n"));
      return (-1);
   }
 
   _tprintf(TEXT("\nTarget directory is %s\n\n"), argv[1]);
 
   // Prepare string for use with FindFile functions.  First, copy the
   // string to a buffer, then append '\*' to the directory name.
 
   StringCchCopy(szDir, MAX_PATH, argv[1]);
   StringCchCat(szDir, MAX_PATH, TEXT("\\*"));
 
   // Find the first file in the directory.
 
   hFind = FindFirstFile(szDir, &ffd);
 
   if (INVALID_HANDLE_VALUE == hFind) 
   {
      ErrorHandler(TEXT("FindFirstFile"));
      return dwError;
   } 
   
   // List all the files in the directory with some info about them.
 
   do
   {
      if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
      {
         _tprintf(TEXT("  %s   <DIR>\n"), ffd.cFileName);
      }
      else
      {
         filesize.LowPart = ffd.nFileSizeLow;
         filesize.HighPart = ffd.nFileSizeHigh;
         _tprintf(TEXT("  %s   %ld bytes\n"), ffd.cFileName, filesize.QuadPart);
      }
   }
   while (FindNextFile(hFind, &ffd) != 0);
 
   dwError = GetLastError();
   if (dwError != ERROR_NO_MORE_FILES) 
   {
      ErrorHandler(TEXT("FindFirstFile"));
   }
 
   FindClose(hFind);
   return dwError;
}
 
 
void ErrorHandler(LPTSTR lpszFunction) 
{ 
    // Retrieve the system error message for the last-error code
 
    LPVOID lpMsgBuf;
    LPVOID lpDisplayBuf;
    DWORD dw = GetLastError(); 
 
    FormatMessage(
        FORMAT_MESSAGE_ALLOCATE_BUFFER | 
        FORMAT_MESSAGE_FROM_SYSTEM |
        FORMAT_MESSAGE_IGNORE_INSERTS,
        NULL,
        dw,
        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
        (LPTSTR) &lpMsgBuf,
        0, NULL );
 
    // Display the error message and exit the process
 
    lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT, 
        (lstrlen((LPCTSTR)lpMsgBuf)+lstrlen((LPCTSTR)lpszFunction)+40)*sizeof(TCHAR)); 
    StringCchPrintf((LPTSTR)lpDisplayBuf, 
        LocalSize(lpDisplayBuf) / sizeof(TCHAR),
        TEXT("%s failed with error %d: %s"), 
        lpszFunction, dw, lpMsgBuf); 
    MessageBox(NULL, (LPCTSTR)lpDisplayBuf, TEXT("Error"), MB_OK); 
 
    LocalFree(lpMsgBuf);
    LocalFree(lpDisplayBuf);
}

Open in new window

This one is on us!
(Get your first solution completely free - no credit card required)
UNLOCK SOLUTION

Gain unlimited access to on-demand training courses with an Experts Exchange subscription.

Get Access
Why Experts Exchange?

Experts Exchange always has the answer, or at the least points me in the correct direction! It is like having another employee that is extremely experienced.

Jim Murphy
Programmer at Smart IT Solutions

When asked, what has been your best career decision?

Deciding to stick with EE.

Mohamed Asif
Technical Department Head

Being involved with EE helped me to grow personally and professionally.

Carl Webster
CTP, Sr Infrastructure Consultant
Empower Your Career
Did You Know?

We've partnered with two important charities to provide clean water and computer science education to those who need it most. READ MORE

Ask ANY Question

Connect with Certified Experts to gain insight and support on specific technology challenges including:

  • Troubleshooting
  • Research
  • Professional Opinions
Unlock the solution to this question.
Join our community and discover your potential

Experts Exchange is the only place where you can interact directly with leading experts in the technology field. Become a member today and access the collective knowledge of thousands of technology experts.

*This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

OR

Please enter a first name

Please enter a last name

8+ characters (letters, numbers, and a symbol)

By clicking, you agree to the Terms of Use and Privacy Policy.