На основе этот ответ на связанный вопрос, я попытался написать метод, который преобразует стандартную строку в широкую строку, которую я затем могу преобразовать в wchar_t *.
Почему нет двух разных способов создания эквивалента wchar_t *? (Я показал значения, которые дает мне мой отладчик).
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?!)
}
где GetWideString определяется следующим образом:
inline const std::wstring GetWideString(const std::string &str)
{
std::wstring wstr;
wstr.assign(str.begin(), str.end());
return wstr;
};
Примечание: следующее тоже не работает.
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();
};
Каждый раз, когда вы звоните GetWideString()
Вы создаете новый std::wstring
, который имеет недавно выделенный буфер памяти. Вы сравниваете указатели на разные блоки памяти (если Assert::AreEqual()
просто сравнивая указатели сами, а не содержание блоков памяти, на которые указывают).
Обновить: const wchar_t* wchar2 = GetWideString("me").c_str();
не работает, потому что GetWideString()
возвращает временный std::wstring
это выходит за рамки и освобождается, как только утверждение закончено. Таким образом, вы получаете указатель на временный блок памяти, а затем оставляете этот указатель свисающим, когда эта память освобождается, прежде чем вы сможете использовать указатель для чего-либо.
Также, const wchar_t* wchar2 = GetWChar("me");
не должен компилироваться. GetWChar()
возвращает std::wstring
, который не реализует неявное преобразование в wchar_t*
, Вы должны использовать c_str()
способ получить wchar_t*
из std::wstring
,
Потому что два указателя не равны. wchar_t *
это не String
так что вы получите универсальный AreEqual.
std::wstring
содержит широкие символы типа wchar_t
, std::string
содержит символы типа char
, Для специальных символов, хранящихся в std::string
используется многобайтовая кодировка, то есть некоторые символы представлены двумя символами в такой строке. Таким образом, преобразование между ними не может быть легким, как вызов простого assign
,
Для преобразования между «широкими» и многобайтовыми строками вы можете использовать следующие помощники (только для Windows):
// 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;
}