Search code examples
c++windowsodbcwstring

How to assemble a string of wide characters with some null ones inserted in the middle of it?


Let's start with the background. I need to set a string of attributes for an ODBC command:

SQLConfigDataSource(hwndParent, ODBC_ADD_DSN, sDriver, wcAttrs);

The attributes have to be formatted in a strict way to work:

LPCWSTR wcAttrs = L"DSN=NiceDB\0DBQ=C:\\Users\\who\\AppData\\Local\\NiceApp\\niceDB.accdb\0";

Hard coding it this way is working, but I actually need to dynamically set the path of the accdb file (DBQ). The issue are the required null characters separating the attributes in the string, and my string-fu skills mainly using wcscat_s fail because the null characters makes anything disappear after it.

What would be the best technique to assemble/concatenate strings with those null characters in the middle ?


Solution

  • You can push_back a null char into a std::wstring as you build it.

    Example:

    std::wstring str;
    str += L"DSN=NiceDB";
    str.push_back(L'\0');
    str += L"DBQ=C:\\Users\\who\\AppData\\Local\\NiceApp\\niceDB.accdb";
    str.push_back(L'\0');
    

    You can also manually append the null char using the += operator:

    std::wstring str;
    str += L"DSN=NiceDB";
    str += L'\0';
    str += L"DBQ=C:\\Users\\who\\AppData\\Local\\NiceApp\\niceDB.accdb";
    str += L'\0';
    

    You can also just tell the append method to use +1 characters of the string literal. That will implicitly pad the std::string with the null char already in the source:

    std::wstring str;
    const wchar_t* header = L"DSN=NiceDB";
    const wchar_t* footer = L"DBQ=C:\\Users\\who\\AppData\\Local\\NiceApp\\niceDB.accdb";
    
    str.append(header, wcslen(header) + 1);
    str.append(footer, wcslen(footer) + 1);
    

    Then to get the pointer to the start of the final string:

    LPCWSTR wcAttrs = str.c_str();
    

    The validity of the pointer returned by .c_str() is only good for the lifetime of the backing wstring. Don't let the wstring instance go out of scope while there's still something referencing wcAttrs.