Velvet Star Monitor

Standout celebrity highlights with iconic style.

general

PathFindExtensionW always return "." instead of full extension

Writer Andrew Mclaughlin

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

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

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.