Finding number of files

I am using FindFirstFile()/FindNextFile() to get the number of files of a specific type in a folder.

Then I am creating a dynamic string array based on the number of files.

Then I am using FindFirstFile()/FindNextFile() to go back through and get the filename of each file into my newly created string array.

IOW, I am using iterating through the files twice to get the data I need. I know I can create a static string, but I don't want that. I only want a dynamic string based on the number of files of specific type in that folder.

This works fine so far, but I want to know if this is the best way to get the number of files of a specific type in a folder and then put the filenames into a dynamic string which has been created based on the number of files.

For example, I am using FindFirstFile()/FindNextFile() to get the number of files of a specific type. Then I am creating my string thus...

char (*ch)[MAX_PATH];
ch = new char[numfiles][MAX_PATH];

Now I am going back through the folder with FindFirstFile()/FindNextFile() once again to get the filename of each file into my string array.

Is this the best way to do this in C/C++. No STL, MFC, etc.
Last edited on
closed account (S6k9GNh0)
It's one of the better ways to do it using the Win32 API...

Although, you should create the string first, then iterate and grab the string at the same time. This is great cause for a vector in the fact that it will save speed and time (to an extent of course). If you need help on the vector, you may look at cplusplus.com reference.
Thanks for the reply. Someone else gave me an example of how to use vector in my example, but he didn't tell me how to access the string once I got it.

IOW, he did this...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <windows.h>
#include <string>
#include <vector>
using namespace std;

vector<string> files;
WIN32_FIND_DATA fd;
HANDLE h = FindFirstFile("*.bmp", &fd);
if (h != INVALID_HANDLE_VALUE) {
    do {
        files.push_back(fd.cFileName) 

    } while (FindNextFile(h, &fd));
    FindClose(h);
}

int count = files.size();


So my question is, how do I access each element of the string now that I got it? I went through the watch window and saw that vector gave me the string in the loop above, but after the loop as finished, I have no idea how to access the string. I've tried a number of ways, but all to no avail.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#include <windows.h>
#include <tchar.h>

#define SEARCH_PATH	"*.*"
#define MAX_FILES	100

BOOL EnumerateFiles(__in_z LPTSTR lptszSearchPath, __out int nFileCount, __out LPTSTR lptszFiles[])
{
	WIN32_FIND_DATA	FindData;
	HANDLE		hFiles;
	LPTSTR		lptszFiles[MAX_FILES];
	UINT		nFileCount = 0;
	BOOL		bRet = FALSE;

	if((hFiles = FindFirstFile(SEARCH_PATH, &FindData)) != NULL)
	{
		for(; FindNextFile(hFiles, &FindData); nFileCount++)
			_tcscpy(lptszFiles[nFileCount++], _T(FindData.cFileName));
		bRet = TRUE;
	}
	return bRet;
}

int __cdecl _tmain(__in int argc, __in_ecount_z(argc) _TCHAR* argv[], __in_z _TCHAR* envp[])
{
	LPTSTR		lptszFiles[MAX_FILES];
	UINT		nFileCount = 0, i;
	BOOL		bRet;

	bRet = EnumerateFiles(_T(SEARCH_PATH), nFileCount, lptszFiles);
	if(bRet)
	{
		_tprintf("Number of files found: %i\n", nFileCount);
		for(i = 0; i < nFileCount; i++)
			_tprintf("\t- File [#%i]: %s\n", i, lptszFiles[i]);
	}
	else
	{
		_tprintf("fucked up enumerating files");
	}

	return (bRet ? EXIT_SUCCESS : EXIT_FAILURE);
}


?
Thanks for the example. I don't understand all of it, but I think I understand most of it, and I think I can figure out the rest with the compiler and the VS C++ help file.
INVALID_HANDLE_VALUE is not NULL, it's -1. The line:
if((hFiles = FindFirstFile(SEARCH_PATH, &FindData)) != NULL)
isn't doing what you think.
-1/INVALID_HANDLE_VALUE as a HANDLE value is a handle to its own process. Checking a HANDLE against INVALID_HANDLE_VALUE is one of the most commonly made mistakes..
Checking a HANDLE against INVALID_HANDLE_VALUE is one of the most commonly made mistakes..


Umm... not when the function returns INVALID_HANDLE_VALUE on failure. Then it's not a mistake, but is actually what you're supposed to do. kbw is correct, you should not be looking for NULL. NULL is meaningless in this context.

Reference:

http://msdn.microsoft.com/en-us/library/aa364418(VS.85).aspx

Specifically:


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.


Also if you truely want any file, use "*" as a wildcard string. "*.*" only accepts filenames with a . in them (ie: files with no extension like "README" would not be detected).
Oops, I was thinking about something else. Never mind, kbw's right.
Topic archived. No new replies allowed.