Best way to convert from std::wstring to std::string?
-
It has been awhile since I've looked this deeply into things. Is the following a good way to convert from a wstring to a string?
std::string dwl::convertWstrToStdString(const std::wstring & wStr) {
const std::locale & loc = std::wcout.getloc();
std::string str;
str.resize(wStr.size()); //If there are cases where the string takes more characters
//than the wstring, we've got a problem.
std::string::iterator it = str.begin();
for (std::wstring::const_iterator wit = wStr.begin(); wit != wStr.end(); ++wit) {
*it = std::use_facet<std::ctype<wchar_t> >(loc).narrow(*wit);
++it;
}
return str;
}Or is the 'str.resize' note (or something else) going to bite in the future? Will the str iterator correctly increment if the character it points to will be a Multi Byte character? Should I just use WideCharToMultiByte() and massage it into a std::string? Thanks, David
My website :: The astronomy of our ancestors: Book :: Videos
-
It has been awhile since I've looked this deeply into things. Is the following a good way to convert from a wstring to a string?
std::string dwl::convertWstrToStdString(const std::wstring & wStr) {
const std::locale & loc = std::wcout.getloc();
std::string str;
str.resize(wStr.size()); //If there are cases where the string takes more characters
//than the wstring, we've got a problem.
std::string::iterator it = str.begin();
for (std::wstring::const_iterator wit = wStr.begin(); wit != wStr.end(); ++wit) {
*it = std::use_facet<std::ctype<wchar_t> >(loc).narrow(*wit);
++it;
}
return str;
}Or is the 'str.resize' note (or something else) going to bite in the future? Will the str iterator correctly increment if the character it points to will be a Multi Byte character? Should I just use WideCharToMultiByte() and massage it into a std::string? Thanks, David
My website :: The astronomy of our ancestors: Book :: Videos
After more searching, I went with the following. CStrWrap is just a thin wrapper around a char array, with a destructor that frees the memory.
std::string dwl::convertWstrToStdString(const std::wstring & wStr) {
//The following code is modified from the examples at http://msmvps.com/blogs/gdicanio/
//archive/2010/01/04/conversion-between-unicode-utf-16-and-utf-8-in-c-win32.aspxif (wStr == L"" || wStr.size()==0) return "";
//Now, get the size of the required string:
int origSize = wStr.size();
origSize++; //For a NULL terminator
DWORD conversionFlags = 0;
//First, get the required size:
int requiredSize = WideCharToMultiByte(CP_ACP, conversionFlags, wStr.c_str(),
origSize, NULL, 0, NULL, NULL);
if (requiredSize == 0)
throw DwlException(_T("Bad Wide String to String conversion"));
CStrWrap cStr(requiredSize+1);
int result = WideCharToMultiByte(CP_ACP, conversionFlags, wStr.c_str(),
origSize, cStr[0], requiredSize, NULL, NULL);
if (result==0) throw DwlException(_T("Error converting string"));
*cStr[result] = '\0';
return std::string(cStr[0]);
}If anyone sees any issues with it, please let me know. Thanks! EDIT - And for std::string to std::wstring:
std::wstring dwl::convertStdStringToWString(const std::string & str) {
//This converts a string to a UNICODE string by the method taken on
//http://www.codeguru.com/forum/archive/index.php/t-231165.html.
if (str.length() == 0) return L"";
//Get the required length:
int unicodeLength = MultiByteToWideChar(CP_ACP, 0, str.c_str(), str.length(), 0, 0);
++unicodeLength; //Add space for a NULL terminator.
if (unicodeLength == 0) throw DwlException(_T("Empty conversion"));
MbStrWrap wStr(unicodeLength);
int result = MultiByteToWideChar(CP_ACP, 0, str.c_str(), str.length(), wStr[0],
unicodeLength);
if (result==0) throw DwlException(_T("Error converting string"));
*wStr[result] = L'\0';
return std::wstring(wStr[0]);
}My website :: The astronomy of our ancestors: Book :: Videos
modified on Sunday, January 9, 2011 1:28 AM
-
It has been awhile since I've looked this deeply into things. Is the following a good way to convert from a wstring to a string?
std::string dwl::convertWstrToStdString(const std::wstring & wStr) {
const std::locale & loc = std::wcout.getloc();
std::string str;
str.resize(wStr.size()); //If there are cases where the string takes more characters
//than the wstring, we've got a problem.
std::string::iterator it = str.begin();
for (std::wstring::const_iterator wit = wStr.begin(); wit != wStr.end(); ++wit) {
*it = std::use_facet<std::ctype<wchar_t> >(loc).narrow(*wit);
++it;
}
return str;
}Or is the 'str.resize' note (or something else) going to bite in the future? Will the str iterator correctly increment if the character it points to will be a Multi Byte character? Should I just use WideCharToMultiByte() and massage it into a std::string? Thanks, David
My website :: The astronomy of our ancestors: Book :: Videos
You can easily convert if you use an intermediate class like
CString
or_bstr_t
. UsingCString
-wstring wstr(L"Wide String");
CStringA cstr(wstr.c_str());
string str(cstr);str = "String";
CStringW wcstr(str.c_str());
wstr = wcstr;Using
_bstr_t
;_bstr_t bstr1(wstr.c_str());
str = (char*)bstr1;_bstr_t bstr2(str.c_str());
wstr = (wchar_t*)bstr2;«_Superman_» _I love work. It gives me something to do between weekends.
-
You can easily convert if you use an intermediate class like
CString
or_bstr_t
. UsingCString
-wstring wstr(L"Wide String");
CStringA cstr(wstr.c_str());
string str(cstr);str = "String";
CStringW wcstr(str.c_str());
wstr = wcstr;Using
_bstr_t
;_bstr_t bstr1(wstr.c_str());
str = (char*)bstr1;_bstr_t bstr2(str.c_str());
wstr = (wchar_t*)bstr2;«_Superman_» _I love work. It gives me something to do between weekends.
Thanks. I wasn't aware of those possibilities.
My website :: The astronomy of our ancestors: Book :: Videos
-
You can easily convert if you use an intermediate class like
CString
or_bstr_t
. UsingCString
-wstring wstr(L"Wide String");
CStringA cstr(wstr.c_str());
string str(cstr);str = "String";
CStringW wcstr(str.c_str());
wstr = wcstr;Using
_bstr_t
;_bstr_t bstr1(wstr.c_str());
str = (char*)bstr1;_bstr_t bstr2(str.c_str());
wstr = (wchar_t*)bstr2;«_Superman_» _I love work. It gives me something to do between weekends.
-
i think we need to set correct locale first (setlocale) , right ?
If u can Dream... U can do it
If you do not specify a locale, the default will be used.
«_Superman_» _I love work. It gives me something to do between weekends.