Reputation: 2407
Based on this answer to a related question, I tried to write a method that converts a standard string to a wide string, which I can then convert into a wchar_t*.
Why aren't the two different ways of creating the wchar_t* equivalent? (I've shown the values that my debugger gives me).
TEST_METHOD(TestingAssertsWithGetWideString)
{
std::wstring wString1 = GetWideString("me");
const wchar_t* wchar1 = wString1.c_str(); // wchar1 = "me"
const wchar_t* wchar2 = GetWideString("me").c_str(); // wchar2 = "ﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮ@" (Why?!)
}
where GetWideString is defined as follows:
inline const std::wstring GetWideString(const std::string &str)
{
std::wstring wstr;
wstr.assign(str.begin(), str.end());
return wstr;
};
Note: the following doesn't work either.
const wchar_t* wchar2 = GetWChar("me");
const wchar_t *GetWChar(const std::string &str)
{
std::wstring wstr;
wstr.assign(str.begin(), str.end());
return wstr.c_str();
};
Upvotes: 0
Views: 1930
Reputation: 595369
Each time you call GetWideString()
, you are creating a new std::wstring
, which has a newly allocated memory buffer. You are comparing pointers to different memory blocks (assuming Assert::AreEqual()
is simply comparing the pointers themselves and not the contents of the memory blocks that are being pointed at).
Update: const wchar_t* wchar2 = GetWideString("me").c_str();
does not work because GetWideString()
returns a temporary std::wstring
that goes out of scope and gets freed as soon as the statement is finished. Thus you are obtaining a pointer to a temporary memory block, and then leaving that pointer dangling when that memory gets freed before you can use the pointer for anything.
Also, const wchar_t* wchar2 = GetWChar("me");
should not compile. GetWChar()
returns a std::wstring
, which does not implement an implicit conversion to wchar_t*
. You have to use the c_str()
method to get a wchar_t*
from a std::wstring
.
Upvotes: 2
Reputation: 42085
std::wstring
contains of wide characters of type wchar_t
. std::string
contains characters of type char
. For special characters stored within std::string
a multi-byte encoding is being used, i.e. some characters are represented by 2 characters within such a string. Converting between these thus can not be easy as calling a simple assign
.
To convert between "wide" strings and multi-byte strings, you can use following helpers (Windows only):
// multi byte to wide char:
std::wstring s2ws(const std::string& str)
{
int size_needed = MultiByteToWideChar(CP_UTF8, 0, &str[0], (int)str.size(), NULL, 0);
std::wstring wstrTo(size_needed, 0);
MultiByteToWideChar(CP_UTF8, 0, &str[0], (int)str.size(), &wstrTo[0], size_needed);
return wstrTo;
}
// wide char to multi byte:
std::string ws2s(const std::wstring& wstr)
{
int size_needed = WideCharToMultiByte(CP_ACP, 0, wstr.c_str(), int(wstr.length() + 1), 0, 0, 0, 0);
std::string strTo(size_needed, 0);
WideCharToMultiByte(CP_ACP, 0, wstr.c_str(), int(wstr.length() + 1), &strTo[0], size_needed, 0, 0);
return strTo;
}
Upvotes: 0
Reputation: 182743
Because the two pointers aren't equal. A wchar_t *
is not a String
, so you get the generic AreEqual.
Upvotes: 1