How to Convert Cstring and Std::String Std::Wstring to Each Other

How do you convert CString and std::string std::wstring to each other?

According to CodeGuru:

CString to std::string:

CString cs("Hello");
std::string s((LPCTSTR)cs);

BUT: std::string cannot always construct from a LPCTSTR. i.e. the code will fail for UNICODE builds.

As std::string can construct only from LPSTR / LPCSTR, a programmer who uses VC++ 7.x or better can utilize conversion classes such as CT2CA as an intermediary.

CString cs ("Hello");
// Convert a TCHAR string to a LPCSTR
CT2CA pszConvertedAnsiString (cs);
// construct a std::string using the LPCSTR input
std::string strStd (pszConvertedAnsiString);

std::string to CString: (From Visual Studio's CString FAQs...)

std::string s("Hello");
CString cs(s.c_str());

CStringT can construct from both character or wide-character strings. i.e. It can convert from char* (i.e. LPSTR) or from wchar_t* (LPWSTR).

In other words, char-specialization (of CStringT) i.e. CStringA, wchar_t-specilization CStringW, and TCHAR-specialization CString can be constructed from either char or wide-character, null terminated (null-termination is very important here) string sources.

Althoug IInspectable amends the "null-termination" part in the comments:

NUL-termination is not required.

CStringT has conversion constructors that take an explicit length argument. This also means that you can construct CStringT objects from std::string objects with embedded NUL characters.

Convert CString to std::wstring

To convert CString to std::wstring:

CString hi("Hi");
std::wstring hi2(hi);

And to go the other way, use c_str():

std::wstring hi(L"Hi");
CString hi2(hi.c_str());

Is it safe to convert a std::wstring to cstring?

The shown code is not going to work correctly. std::wstring's c_str() method returns a const wchar_t *. Passing it to std::ostringstream's operator<< will choose the operator<< overload that takes const void * parameter, which will not accomplish anything useful.

You stated that you expect your std::wstring to consist mostly of US-ASCII characters. If so, the hackiest approach is to rudely convert the std::wstring to a std::string, in the following manner, replacing all non-ASCII characters with a question mark (or pick your favorite punctuation symbol):

std::string cvalue;

std::transform(value.begin(), value.end(),
std::back_insert_iterator<std::string>(cvalue),
[](wchar_t wchar)
{
return static_cast<char>(wchar > 127 ? '?':wchar);
});

Proceed, and << the ordinary std::string into your message.

If you expect your wide string to consist mostly of US-ASCII content, this would be a quick hack to get the job done. Otherwise, one would need to use the localization library to properly convert the wide string to a narrow character string using the current system locale. Quite a bit of work...

How to convert wstring into string?

Here is a worked-out solution based on the other suggestions:

#include <string>
#include <iostream>
#include <clocale>
#include <locale>
#include <vector>

int main() {
std::setlocale(LC_ALL, "");
const std::wstring ws = L"ħëłlö";
const std::locale locale("");
typedef std::codecvt<wchar_t, char, std::mbstate_t> converter_type;
const converter_type& converter = std::use_facet<converter_type>(locale);
std::vector<char> to(ws.length() * converter.max_length());
std::mbstate_t state;
const wchar_t* from_next;
char* to_next;
const converter_type::result result = converter.out(state, ws.data(), ws.data() + ws.length(), from_next, &to[0], &to[0] + to.size(), to_next);
if (result == converter_type::ok or result == converter_type::noconv) {
const std::string s(&to[0], to_next);
std::cout <<"std::string = "<<s<<std::endl;
}
}

This will usually work for Linux, but will create problems on Windows.

BSTR to std::string (std::wstring) and vice versa

BSTR to std::wstring:

// given BSTR bs
assert(bs != nullptr);
std::wstring ws(bs, SysStringLen(bs));

 

std::wstring to BSTR:

// given std::wstring ws
assert(!ws.empty());
BSTR bs = SysAllocStringLen(ws.data(), ws.size());

Doc refs:

  1. std::basic_string<typename CharT>::basic_string(const CharT*, size_type)
  2. std::basic_string<>::empty() const
  3. std::basic_string<>::data() const
  4. std::basic_string<>::size() const
  5. SysStringLen()
  6. SysAllocStringLen()

Convert String^ to wstring C++

std::wstring new_wstring(c_string)
where new_wstring is the name of your new wstring, and c_string is the name of your String:
Convert CString to std::wstring



Related Topics



Leave a reply



Submit