Search code examples
c++stdstring

How to convert LPCTSTR to std::string in C++


I am having a function which takes arguments as LPCTSTR

I want to concatenate that argument in that function with a std::string

As per one of the suggestions I used following conversion:

std::string PlaybackStart(LPCTSTR i_bstrCameraName)
{
    wstring cid = (WCHAR*)i_bstrCameraName;
    string fcid;
    for (char x : cid)
        fcid += x;

   std::string myURL = "SOME IP";

   **//I want to concatenate myURL with i_bstrCameraName here**

   return myURL;
}

but this is leading to loss of data for example value passsed in arguments is "abcdefg" but my fcid gets a value as "aceg".


Solution

  • LPCTSTR is an alias for const TCHAR*, where TCHAR is either char or wchar_t, depending on project configuration.

    The cast of i_bstrCameraName to WCHAR* is wrong if your project is configured to map TCHAR to char. Just use the char data as-is instead.

    And the conversion of wchar_t characters to char in the for loop is wrong if TCHAR is configured to map to wchar_t instead. That will lose data for non-ASCII characters. You would need to use WideCharToMultiByte() or equivalent to convert the wchar_t data to char properly.

    You really should not be using TCHAR-based functionality in modern code at all. That has not been needed since the days when Microsoft was migrating users from ANSI-based Win9x/ME to Unicode-based WinNT+.

    But, if you must, your code should look more like this instead:

    std::string PlaybackStart(LPCTSTR i_bstrCameraName)
    {
        string fcid;
    
        #ifdef UNICODE
        int wlen = lstrlenW(i_bstrCameraName);
        int len = WideCharToMultiByte(CP_ACP, 0, i_bstrCameraName, wlen, NULL, 0, NULL, NULL);
        fcid.resize(len);
        WideCharToMultiByte(CP_ACP, 0, i_bstrCameraName, wlen, &fcid[0], len, NULL, NULL);
        #else
        fcid = i_bstrCameraName;
        #endif
    
        std::string myURL = "SOME IP";
    
        myURL += fcid;
    
        return myURL;
    }
    

    That being said, the parameter name i_bstrCameraName suggests that the parameter should actually be declared as a BSTR, not an LPCTSTR. BSTR is an alias for OLECHAR* aka wchar_t*, eg:

    std::string PlaybackStart(BSTR i_bstrCameraName)
    {
        string fcid;
    
        int wlen = SysStringLen(i_bstrCameraName);
        int len = WideCharToMultiByte(CP_ACP, 0, i_bstrCameraName, wlen, NULL, 0, NULL, NULL);
        fcid.resize(len);
        WideCharToMultiByte(CP_ACP, 0, i_bstrCameraName, wlen, &fcid[0], len, NULL, NULL);
    
        std::string myURL = "SOME IP";
    
        myURL += fcid;
    
        return myURL;
    }