I have this code and it displays the folder with the directory itself and not its contents. I want to display its contents. I don't want to use boost::filesystem.
How can I resolve this?
Code:
#include <windows.h>
#include <iostream>
int main()
{
WIN32_FIND_DATA data;
HANDLE hFind = FindFirstFile("C:\\semester2", &data); // DIRECTORY
if ( hFind != INVALID_HANDLE_VALUE ) {
do {
std::cout << data.cFileName << std::endl;
} while (FindNextFile(hFind, &data));
FindClose(hFind);
}
}
Output:
semester2
Harrys answer will actually yield files and folders having an extension in your desired folder
"C:\\semester2"
.So for example if you have a folder named
"C:\\semester2\\math.course"
it will also be found by the above example. Moreover if you will have a file named"C:\\semester2\\math_scores"
(notice it not having an extension) it will not be found.Taking the above into consideration I would suggest the following solution:
This will list the entire listing of items under the directory. Filtering the directories can be done in the following way:
The following can be used for references: FileAttributes constants, FIND_DATA struct, FindFirstFile API
Let me take some notes about
"*.*"
vs"*"
. These filers are not equal.2 different files can exist in our folder:
somefile
andsomefile.
.If we used the low level api
ZwQueryDirectoryFile
with"*.*"
as a search expression (this is the 10th parameter -FileName [in, optional]
) - we would getsomefile.
only. But if we used"*"
we'd get both files -somefile
andsomefile.
If we try
FindFirstFile("C:\\semester2\\*.*", &data);
we can note than both filessomefile
andsomefile.
are returned. So here"*.*"
vs"*"
have the same effect - no difference in usage.Why does this happen? Because inside
FindFirstFileEx
inkernelbase
(kernel32
) do special check for"*.*"
mask and if it true - replace to""
(An empty name which have the same effect as"*"
).I think this is done to fix a very common error when users pass
"*.*"
instead of the correct"*"
and for backward compatability with legacy code.This is not true.
FAT
-style file system this is really stored on FAT directory as 2 first entry.NTFS
there are no such entries, butNTFS.sys
artificially add this 2 entries if they in mask.So this is done not at Win32 API level, but in kernel - on driver level.
In conclusion,
"*.*"
will work correct with Win32 API how minimum now - but the correct and clean way is to use"*"
here."*.*"
will be mistake withZwQueryDirectoryFile
api.You got the directory because that's what you asked for. If you want the files, ask for them:
(You can instead use
*.*
if you prefer, but apparently this only works because of a backwards compatibility hack so should probably be avoided. See comments and RbMm's answer.)