Link to home
Start Free TrialLog in
Avatar of vivekpara
vivekparaFlag for United States of America

asked on

Return filenames to ListBox from array

I got some code from here and modified it to implement it myself in an MFC project I have.  I can't seem to get it to return the file names to my listbox.  What it seems to be doing is sending the address in memory of the pointer of the last file it looks at rather than returning the correct filenames.  Any ideas?

void Readcfgini()
{
      char **dirarray;
      char *scandir;

      scandir = "C:\\UI Code and Executable\\UIMFC\\UIMFC\\Debug\\programs";
      dirarray = 0;
      dirarray = ScanDir( scandir , 0);

      CString temp;
      for(int i=0;i<sizeof(dirarray);i++){

                  /*(int k[sizeof(dirarray)],j;
                  for(j=0;j<sizeof(dirarray);j++)
                  {
                        k[j]=(int)dirarray[j];
                        //cout<<i[j]<<" "; //output the ascii chars
                        temp.Format("%d", k[j]);
                  }*/


            temp.Format("%d", dirarray);
            m_list.AddString(temp);
}



}

char ** ScanDir(char* dirname, int indent)
{
    BOOL            fFinished;
    HANDLE          hList;
    TCHAR           szDir[MAX_PATH+1];
    WIN32_FIND_DATA FileData;
    char ** names = NULL;
    int count = 0 , maxnames = 0;


    // Get the proper directory path
    sprintf(szDir, "%s\\*", dirname);

    // Get the first file
    hList = FindFirstFile(szDir, &FileData);
    if (hList == INVALID_HANDLE_VALUE)
    {
        return NULL;     // No files, return empty list
    }
    else
    {
        // Traverse through the directory structure
        fFinished = FALSE;
        while (!fFinished)
        {
            // Make sure we have enough room in array to add another name
            if (count >= maxnames)
                 names = (char **)realloc(names, (maxnames+=1024)*sizeof(char*));

            // Check the object is a directory or not
            if (FileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
            {
                if ((strcmp(FileData.cFileName, ".") != 0) &&
(strcmp(FileData.cFileName, "..") != 0))
                {
                      names[count] = (char *)malloc(strlen(FileData.cFileName)+2);
                      strcpy(names[count], FileData.cFileName);
                      // add a trailing slash to indicate directory
                      strcat(names[count], "\\");
                      count++;
                }
            }
            else
                        names[count++] = (FileData.cFileName);                  

            if (!FindNextFile(hList, &FileData))
            {
                if (GetLastError() == ERROR_NO_MORE_FILES)
                {
                    fFinished = TRUE;
                }
            }
        }
    }

    return names;
}
Avatar of vivekpara
vivekpara
Flag of United States of America image

ASKER

I think its THIS line that is incorrect in some way...but I'm not sure how:

names[count++] = (FileData.cFileName);  

Or it could be something in my Readcfgini function that is returning the data to the listbox.

Sigh!
SOLUTION
Avatar of jkr
jkr
Flag of Germany image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
BTW, http://www.codeproject.com/dialog/searchfolders.asp ("Browse Folder dialog, search folder and all sub folders using C/C++") seems to really cover your issue.
jkr has it right. You need an allocation for names[count] and a string copy. Instead of strdup you also could repeat the sequence you have in the if branch:
 
       names[count] = (char *)malloc(strlen(FileData.cFileName)+1);
       strcpy(names[count++], FileData.cFileName);

If you later want to change to C++ operator new (replacing malloc) and/or  C++ containers like CStringList, CStringArray or std::vector<string>, you shouldn't forget to replace strdup as well, as strdup uses malloc.
                     
Regards, Alex
I'm trying it, but it seemed easier to recode than to use the old stuff now.  Now how do I return file names in this new code, though?  What I need is a way to store it in the stringarray and then be able to loop through my collection to read each of the files.   I think my sizeof line will not work properly...but I'm not sure.  Also, my knowledge of handles is useless...so if you have any suggestions on how to use them properly...please interject.

      CStringArray astrPaths;
      LPCTSTR name = "C:\\UI Code and Executable\\UIMFC\\UIMFC\\Debug\\programs\\*.cfg";
      WIN32_FIND_DATA data;
      HANDLE fileHandle = FindFirstFile(name, &data);

      for(int i=0;i<sizeof(fileHandle);i++)
            {
            
            if(fileHandle == INVALID_HANDLE_VALUE) {

                  if(GetLastError() == ERROR_FILE_NOT_FOUND)
                  {
                  }
                  else
                  {
                        //astrPaths.Add((LPCTSTR)fileHandle);
                  }
            }
      }
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
This is what I ended up with:

void Readcfgini()
{
      
     CStringArray astrPaths;
     LPCTSTR name = "C:\\UI Code and Executable\\UIMFC\\UIMFC\\Debug\\programs\\*.txt";
     WIN32_FIND_DATA data;
     HANDLE fileHandle = FindFirstFile(name, &data);

     while (fileHandle != INVALID_HANDLE_VALUE)
     {
             astrPaths.Add(data.cFileName);
             m_list.AddString(data.cFileName);
                  
             if (!FindNextFile(fileHandle, &data))
                   break;
     }
     DWORD err;
     if((err = GetLastError()) != ERROR_NO_MORE_FILES)
     {
           return;
     }


}