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 ".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

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;
}
1

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);

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Maya Lin-Takahashi

Maya Lin-Takahashi

Consumer Tech & Gadget Reviewer

Maya is a hardware enthusiast who tests and reviews smart home devices, smartphones, wearables, and audio gear. She focuses on practical consumer value and build quality.

Share this article
Twitter Facebook Pinterest