Pathfindextensionw Always Return "." Instead of Full Extension
I Have the Following Path and Filename "C: \\Users\\Msi\\Desktop\\Read-File\\Read-File. Sdf" with Pathfindextensionw Function, the Expected Return String Is "...
I have the following path and filename
"C:\\Users\\msi\\Desktop\\read-file\\read-file.sdf"
With PathFindExtensionW function, the expected return string is ".sdf" but it returns "." instead!
This is my code :
#include <stdio.h>
#include <shlwapi.h>
#define FILENAME "C:\\Users\\msi\\Desktop\\read-file\\read-file.sdf" // current file-path
#define MAX_FILE_EXT 90 // maximum file-extension length
#define ERR_MSG "Cannot open the specific file!\n" // error message if couldn't open the file
#pragma comment(lib, "shlwapi.lib") // add this static library for using of PathFindExtension
int main(int argc, char *argv[])
{
WIN32_FIND_DATAW data = {0};
HANDLE fh = 0;
if((FindFirstFile(TEXT(FILENAME), &data)) != INVALID_HANDLE_VALUE)
{
WCHAR file_ext[MAX_FILE_EXT] = {0};
lstrcpy(file_ext, PathFindExtension(TEXT(FILENAME)));
printf("File-extension is : '%s'\n", PathFindExtensionW(TEXT(FILENAME)));
}
else
printf(ERR_MSG);
return 0;
}
By the way, I used wchar_t*, so I had to call PathFindExtensionW. Although I called PathFindExtension, it returned the same result.
2 Answers
Your program is Unicode (which is recommended), you don't really need the TEXT macro which only adds L prefix when UNICODE is defined. You can do that yourself:
const wchar_t *wstr = L"this is a wide char string"; //or const WCHAR*, same thing
PathFindExtension is a macro, which is defined as PathFindExtensionW when UNICODE is defined.
#ifdef UNICODE
#define PathFindExtension PathFindExtensionW
#else
#define PathFindExtension PathFindExtensionA
#endif // !UNICODE
So you can just write PathFindExtension
lstrcpy copy is fine, but it is a Windows specific function. New programs can use wide char version of string functions, wcscpy instead of strcpy, wcslen instead of strlen, wcsxxx instead of strxxx ...
"C:\\Users\\msi\\Desktop" should not be hard-coded. Use SHGetKnownFolderPath to find the desktop path, example:
#include <windows.h>
#include <stdio.h>
#include <shlwapi.h>
#include <Shlobj.h>
#include <KnownFolders.h>
#pragma comment(lib, "shlwapi.lib")
int main(void)
{
wchar_t desktop[MAX_PATH];
//get desktop path:
wchar_t *ptr;
SHGetKnownFolderPath(&FOLDERID_Desktop, 0, NULL, &ptr);
wcscpy_s(desktop, _countof(desktop), ptr);
CoTaskMemFree(ptr);
//make filename from desktop path:
wchar_t filename[MAX_PATH];
swprintf(filename, _countof(filename), L"%s\\read-file\\read-file.sdf", desktop);
if (PathFileExists(filename))
wprintf(L"File-extension is : '%s'\n", PathFindExtension(filename));
return 0;
}
When we are intended to use the printf to print out a wide-string, we should use "%ls" format specifier, not "%s".
However, using "%s" with wprintf is perfectly fine.
This is the rule :
WCHAR *wstr = "this is wide string";
CHAR *str = "this is string";
wprintf("%s", wstr);
printf("%ls", wstr);
printf("%s", str);