Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win

x
?
Solved

Return filenames to ListBox from array

Posted on 2004-10-26
7
Medium Priority
?
294 Views
Last Modified: 2012-06-27
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;
}
0
Comment
Question by:vivekpara
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
  • 2
  • 2
7 Comments
 
LVL 2

Author Comment

by:vivekpara
ID: 12415745
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!
0
 
LVL 86

Assisted Solution

by:jkr
jkr earned 400 total points
ID: 12417392
It is indded incorrect, since it only copies a pointer to the struct entry that is reused in the loop, thus having all pointers point to the string that was read last.. Try

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

(you might need to #include <string.h>).

Apart from that, since you mentioned MFC, you'd better use a CStringList for that, e.g.

 CStringList names;

 names.AddTail(CString(FileData.cFileName));
0
 
LVL 86

Expert Comment

by:jkr
ID: 12417638
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.
0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 12424783
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
0
 
LVL 2

Author Comment

by:vivekpara
ID: 12438540
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);
                  }
            }
      }
0
 
LVL 39

Accepted Solution

by:
itsmeandnobodyelse earned 1600 total points
ID: 12442955
    CStringArray astrPaths;
     LPCTSTR name = "C:\\UI Code and Executable\\UIMFC\\UIMFC\\Debug\\programs\\*.cfg";
     WIN32_FIND_DATA data;
     HANDLE fileHandle = FindFirstFile(name, &data);

     while (fileHandle != INVALID_HANDLE_VALUE)
     {
             astrPaths.Add(data.cFileName);
             if (!FindNextFile(fileHandle, &data))
                   break;
     }
     DWORD err;
     if((err = GetLastError()) != ERROR_NO_MORE_FILES)
     {
           cout << "error = " << err << endl;
           return;
     }


Regards, Alex


0
 
LVL 2

Author Comment

by:vivekpara
ID: 12447727
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;
     }


}
0

Featured Post

Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Container Orchestration platforms empower organizations to scale their apps at an exceptional rate. This is the reason numerous innovation-driven companies are moving apps to an appropriated datacenter wide platform that empowers them to scale at a …
Basic understanding on "OO- Object Orientation" is needed for designing a logical solution to solve a problem. Basic OOAD is a prerequisite for a coder to ensure that they follow the basic design of OO. This would help developers to understand the b…
The goal of the video will be to teach the user the difference and consequence of passing data by value vs passing data by reference in C++. An example of passing data by value as well as an example of passing data by reference will be be given. Bot…
The viewer will be introduced to the member functions push_back and pop_back of the vector class. The video will teach the difference between the two as well as how to use each one along with its functionality.
Suggested Courses

636 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question