Link to home
Start Free TrialLog in
Avatar of gav061697
gav061697

asked on

Listing files in a directory

I'm trying to write a function which looks in a certain directory for files matching a specified pattern.  I then want all these files returned in an array.  To accomodate this the array needs to be created dynamically as the number of files in the directory isn't known at compile time.  The array is of type char so it needs to be multi-dimensional.

The only problem I have is that all the array elements have the same value.  Here's my code:

 int FindFiles(char* directory, char** &filelist)
{
   _finddata_t fileinfo;
   int numberfiles = FindNumberFiles(directory);

   int i=0;
   int nElementY = 260;

   // create multi-dimensional array
   filelist = new char* [numberfiles];
   for(i = 0; i < numberfiles; ++i)
      filelist[i] = new char[260];

   numberfiles = 0;

   long findhandle = _findfirst( directory, &fileinfo );
   if(findhandle > -1)
   {
      //set first array element to filename
      filelist[numberfiles] = fileinfo.name;
      numberfiles++;
      while(_findnext(findhandle, &fileinfo) == 0)
      {
         // set next element to new filename
         filelist[numberfiles] = fileinfo.name;
         numberfiles++;
      }
      numberfiles--;
      _findclose(findhandle);
   }

   return numberfiles;
}

fileinfo.name is of type char[260].

Any ideas of how to get this working properly?

Thanks

Gavin Rouse
ASKER CERTIFIED SOLUTION
Avatar of nietod
nietod

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
Avatar of nietod
nietod

When you do that it changes the pointer stored in Filelist[numberfiles] so that it points to a new location, in other words so it points to fileinfo.name.  But the string stored in fileinfo.name will change each time you find a new file, so this filelist[numberfiles] pointer will point to a string that is changing.  

Understand.  

One fix would be to use strcpy() to copy the string from filinfo.name to the filelist[numberfiles] entry.  Like

strcpy(filelist[numberfiles],fileinfo.name);

That will work.  but that is C-type solution.  Thee are lots of dangers in the whole approach.  what if 260 characters is not enough?  What if the number of files in the directory changes between the time you count the files and the time you read the files?  What if you forget to delete the file names or the array of file name pointers?

Too many potential probkems.
Instead, you should use a string class instead of a "char *" string.  The stl string class is one posibility.  There are others.  They allow you to copy strings with =.  They also insure that the string's memory is deleted when not longer needed.  They are also usually much faster and more memory efficient.

Also you should not use a regular array to store information when the array's size must change.  You should use an array class.   Again the stl has one called vector.   An array class will usually resize as needed, without requiring you to copy information.  The will delete the memory used when no longer needed.  And they usually support many operations that regular arrays don't, like insertion in the middle.
Avatar of gav061697

ASKER

That's exaclty what I thought.  I have tried using vector together with string but had trouble getting it working.  One problem was that it gave a compiler warning saying something was too long for debugging and so was truncated.  Maybe I should look into it a bit more as it is a much better solution.  One problem is I haven't done much C++ programming, more MFC which has its own classes for this eg CArray and the C++ book i've got doesn't cover STL so I don't know much about it.

Incidentally, 260 characters will be enough as that is the size of the fileinfo.name array.
>> One problem was that it gave a compiler
>> warning saying something was too long
>> for debugging and so was truncated
That's a warning, not an error.  You can ignore it. Furthermore, I think it was fixed in version 6.  If you aren't on VC 6, I really recommend you upgrade.

>> the C++ book i've got doesn't cover STL
Try Bjarne Stroustrup's "The C++ Programming Language".  its got not intensively on STL, but it does vcover it and its got lots of other good topics too.  There are also some Web sites that cover it, but I don't have the links handy right now.  (I'm in a hurry.)

>> tried using vector together with string but
>> had trouble getting it working                  
What sort of problems?

Note I'm leaveing for 4 or 5 days in a few hours, so I can't get back to you until i get back.
I would love to upgrade, but not everyone, especially students like me, have that kind of money to splash out on things.

>>>> tried using vector together with string but
>>>> had trouble getting it working                    
>>What sort of problems?

Nothing major, just passing the vector as a parameter to the function and getting the values out of it afterwards.  But these were probably caused by my inexperience with STL.

Anyway, I got it working using strcpy, and for what I am using it for (a simple game), it shouldn't pose a problem, but i'll try to get the STL version working anyway just as a learning experience.

Thanks for your help.
>> just passing the vector as a parameter to
>> the function and getting the values out of
>> it afterwards
Did you pass the vector by value?  You need to pass it by reference.  An STL vector is a class so it can be passed by value, which means the function called gets a copy of the vector and works  with the copy.  The caller's vector, is a seperate copy and remains unchanged. If you pass by reference, the function works with the caller's copy of the vector.

(This can't happen with a regular array, because C/C++ never permits arrays to be passed by value.