Search code examples
c++boost

wchar parameters using boost or the Standard Library


How can I make this code use the boost C++ string library or the Standard Library, to avoid wchar_t size definition, and to have a more dynamic string which can be processed much easier? This code uses MFC's CString, but I would prefer to use the Standard Library or boost instead.

TCHAR       drive[_MAX_DRIVE];
TCHAR       dir[_MAX_DIR];
TCHAR       fname[_MAX_FNAME];
TCHAR       ext[_MAX_EXT];
CString     cstr;

GetModuleFileName(NULL,cstr.GetBuffer(MAX_PATH),MAX_PATH);
cstr.ReleaseBuffer();

_wsplitpath_s(cstr,drive,dir,fname,ext);
cstr=drive;
cstr+=dir;
cstr+=_T("\\myfile.dat");

Solution

  • You should have a look at the C++ standard <filesystem> library, specifically its path class, which has a replace_filename() method, eg:

    #include <filesystem>
    #include <windows.h>
    
    WCHAR szFileName[MAX_PATH] = {};
    GetModuleFileNameW(NULL, szFileName, MAX_PATH);
    std:wstring str = std::filesystem::path(szFileName).replace_filename(L"myfile.dat").wstring();
    

    Or, since you are using the Win32 API anyway, you could simply use PathRemoveFileSpec() and PathAppend() instead (or their safer Cch counterparts), eg:

    #include <windows.h>
    
    WCHAR szFileName[MAX_PATH] = {};
    GetModuleFileNameW(NULL, szFileName, MAX_PATH);
    PathRemoveFileSpecW(szFileName);
    PathAppendW(szFileName, L"myfile.dat");
    std:wstring str = szFileName;
    

    If you really want to avoid the MAX_PATH restriction, you will have to call GetModuleFileName() in a loop, increasing the size of the buffer on each iteration, until it finally succeeds:

    std::wstring wFileName(MAX_PATH, L'\0');
    do {
        DWORD dwSize = GetModuleFileNameW(NULL, wFileName.data(), wFileName.size()); // or &wFileName[0] before C++17
        if (dwSize < wFileName.size()) {
            wFileName.resize(dwSize);
            break;
        }
        wFileName.resize(wFileName.size() * 2);
    }
    while (true);
    // use wFileName as needed...