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